Google provides the following code to get a gmail draft
public static Draft getDraft(Gmail service, String userId, String draftId)
throws IOException {
Draft draft = service.users().drafts().get(userId, draftId).execute();
Message message = draft.getMessage();
System.out.println("Draft id: " + draft.getId() + "\nDraft Message:\n"
+ message.toPrettyString());
return draft;}
My question is : Can I get a MimeMessage from the Message? If I could, I would update this MimeMessage with multiple attachments. Or if anyone else knows how to update a draft with multiple attachments, please advice.
Related
currently I'm creating an email service for my hobby project for newly signed up users. This is the relevant part of the code, which causes me some headache:
private Message createEmail(String firstName, String password, String email) throws MessagingException {
Message message = new MimeMessage(getEmailSession());
message.setFrom(new InternetAddress(FROM_EMAIL));
message.setRecipient(Message.RecipientType.TO, InternetAddress.parse(email, false)[0]);
message.setRecipient(Message.RecipientType.CC, InternetAddress.parse(CC_EMAIL, false)[0]);
message.setSubject(EMAIL_SUBJECT);
message.setText("Hello " + firstName + ", \n \n Your new account password is: " + password + "\n \n " +
"The support team");
message.setSentDate(new Date());
message.saveChanges();
return message;
}
I have two problems with this line message.setRecipient(Message.RecipientType.TO, InternetAddress.parse(email, false)[0]); (and of course the same problem with the next line below it):
On the internet, if I google after it, everywhere it is used like this:
message.setRecipient(Message.RecipientType.TO, InternetAddress.parse(email, false);
so, without the indexing. But if I remove the indexing, I get an IDE error, which says, that the function requires a type of Address, but it has got InternetAddress[], an array. That's why I put the indexing.
But if I leave the indexing and run the app and register a new user, I get the error in the console: Index 0 out of bounds for length 0. Obviously, the InternetAddress[] array is empty. But why?
What exactly is going on here?
Looking at the docs, it should be new InternetAddress(String, boolean), which
Parse[s] the given string and create[s] an InternetAddress.
instead of InternetAddress.parse(String, boolean), which
Parse[s] the given sequence of addresses into InternetAddress objects.
I am trying to access emails on a Office365 mailbox, using Exchange Web Services (EWS).
My O365 admin has created :
the shared mailbox : shared#domain.com
the account : my.account#domain.com
a group, giving access to the account on the mailbox
I am able to retrieve the Oauth token using the appId/tenantId and a UserNamePasswordParameters using the account's credentials, and now I am trying to retrieve the emails from the mailbox, but I get this error :
microsoft.exchange.webservices.data.core.exception.service.remote.ServiceResponseException:
Mailbox does not exist.
here's my code :
public Iterable fetchEmails(String token, String account) throws Exception {
if(token==null) {
token = getToken();
}
FindItemsResults<Item> emails;
try (ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2)) {
service.getHttpHeaders().put("Authorization", "Bearer " + token);
service.setUrl(new URI("https://outlook.office365.com/EWS/Exchange.asmx"));
service.setWebProxy(new WebProxy(PROXY_HOST, PROXY_PORT));
FolderId folder = new FolderId(WellKnownFolderName.Inbox, new Mailbox(account));
emails = service.findItems(folder, new ItemView(15));
}
return emails;
}
OK, it was a bit stupid.. I got confused because the account is also an email..
solution is to pass the mailbox (shared#domain.com) instead of the account (my.account#domain.com) when building the Mailbox object :
FolderId folder = new FolderId(WellKnownFolderName.Inbox, new Mailbox("shared#domain.com"));
And now it's working, I am able to get the emails.
I trained succesfully my own NLP AutoML model yesterday. I am able to do quite accurate predictions in GCP console. Everything ran smoothly. Today I have been trying to do prediction from Java client based on this example https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/language/automl/src/main/java/com/google/cloud/language/samples/PredictionApi.java
I use correct projectId and modelId that I copied from GCP console but I am waiting for result forever. Even after couple of minutes there is still no response. There is no exception thrown. I use europe-west3 as computeRegion.
Strange thing is that I also use Java client for Google NLP Sentiment Analysis and it works without problems and returns response immediately (based on this example https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/language/cloud-client/src/main/java/com/example/language/QuickstartSample.java)
Both clients are connected to the same GCP project (have the same projectId) but only one of them is working properly.
Do you please have some clue what could be wrong?
Thank you in advance for any hints
This is the code:
public class PredictionApi {
public static void main(String[] args) throws IOException {
PredictionApi predictionApi = new PredictionApi();
predictionApi.predict("projectId", "us-central1", "modelId");
}
private void predict(String projectId, String computeRegion, String modelId) throws IOException {
PredictionServiceClient predictionClient = PredictionServiceClient.create();
ModelName name = ModelName.of(projectId, computeRegion, modelId);
String content = "BERLIN Germany and China want to sign two agreements to deepen their cooperation in the financial sector later this week a German government document seen by Reuters showed on Wednesday";
TextSnippet textSnippet =
TextSnippet.newBuilder().setContent(content).setMimeType("text/plain").build();
ExamplePayload payload = ExamplePayload.newBuilder().setTextSnippet(textSnippet).build();
Map<String, String> params = new HashMap<String, String>();
PredictResponse response = predictionClient.predict(name, payload, params);
System.out.println("Prediction results:");
for (AnnotationPayload annotationPayload : response.getPayloadList()) {
System.out.println("Predicted Class name :" + annotationPayload.getDisplayName());
System.out.println(
"Predicted Class Score :" + annotationPayload.getClassification().getScore());
}
}
}
europe-west3 is not supported. All trained automl models are currently served in us-central1. You should in theory receive some error like what you reported in another stackoverflow post. I am a bit surprised you didn't receive any error message from the server. Do you mind share your client side code?
I have a GSuite account for my organization. I want to use Gmail API to send mail in my Java app but I don't want to use Oauth2 authent. I follow this documentation to delegate authority to a service account https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority.
I followed these steps:
configure a new account service
activate Gmail API in the dev console
associate rights between my client ID and the API
My Kotlin code to be able to initialize the Gmail service is below (the code is equivalent in Java)
#Configuration
class MixitApplication {
#Bean
fun jacksonFactory() = JacksonFactory.getDefaultInstance()
#Bean
fun dataStoreFactory() = MemoryDataStoreFactory.getDefaultInstance()
#Bean
fun httpTransport() = GoogleNetHttpTransport.newTrustedTransport()
#Bean
fun authorize(): Credential {
val jsonConfig = "{\n" +
" \"type\": \"service_account\",\n" +
" \"project_id\": \"mixit-EeAZEAZE\",\n" +
" \"private_key_id\": \"FAKE\",\n" +
" \"private_key\": \"-----BEGIN PRIVATE KEY-----\\FAKE\\n-----END PRIVATE KEY-----\\n\",\n" +
" \"client_email\": \"website#FAKE.iam.gserviceaccount.com\",\n" +
" \"client_id\": \"FAKE\",\n" +
" \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\n" +
" \"token_uri\": \"https://accounts.google.com/o/oauth2/token\",\n" +
" \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\",\n" +
" \"client_x509_cert_url\": \"https://www.googleapis.com/robot/v1/metadata/x509/website%40mixit-196820.iam.gserviceaccount.com\"\n" +
"}"
return GoogleCredential
.fromStream(jsonConfig.byteInputStream())
.createScoped(listOf(GmailScopes.GMAIL_SEND))
}
#Bean
fun gmailService() = Gmail.Builder(httpTransport(), jacksonFactory(), authorize()).build()
}
In my service when I try to end an email with this code
val result = gmailService.users().messages().send("me", emailMessage).execute();
I have always this error
400 Bad Request { "code" : 400, "errors" : [ { "domain" : "global", "message" : "Bad Request", "reason" : "failedPrecondition" } ], "message" : "Bad Request" }
I found several posts about similar problem. But it's often because the account is not a Gsuite account
I tried to find Google support for this problem but I had no solution for the moment. There' no information on the Google API console. I just know that I had a bad request.
My email function to send mail is very simple. EmailMessage is a custom object with email infos (to, subject and content)
fun send(email: EmailMessage) {
val session = Session.getDefaultInstance(Properties(), null)
val message = MimeMessage(session)
message.setFrom(InternetAddress("me"))
message.addRecipient(javax.mail.Message.RecipientType.TO, InternetAddress(email.to))
message.subject = email.subject
message.setContent(email.content, MediaType.TEXT_HTML_VALUE)
val buffer = ByteArrayOutputStream()
message.writeTo(buffer)
val emailMessage = Message()
emailMessage.encodeRaw(buffer.toByteArray())
val result = gmailService.users().messages().send("me", emailMessage).execute();
System.out.println(result.toPrettyString())
}
When I try to send this message by the test api console I https://developers.google.com/apis-explorer/?hl=en_GB#p/gmail/v1/gmail.users.messages.send the message is sent
Can you help me?
Using Gmail API requires OAuth2 authorization, even service accounts uses Oauth2.0:
All requests to the Gmail API must be authorized by an authenticated
user. Gmail uses the OAuth 2.0 protocol for authenticating a Google
account and authorizing access to user data. You can also use Google+
Sign-in to provide a "sign-in with Google" authentication method for
your app.
In short, you need to use OAuth2.0. You can check the implemenation of service account in this SO post.
Our application send emails automatically, and I need those emails to be grouped in threads, so the user have them organized in their mailboxes. These emails could have different subjects as well. For example:
Issue 93 created
Issue 93 description changed
Issue 93 assignee changed
Issue 94 created
Issue 94 closed
I'm trying to set the "In-Reply-To" header of every child email to point to the parent mail Message-ID. So, every time a new issue is created, and the first mail is sent, I will save its Message-ID. When a new email related to the issue is going to be sent, I will add a "In-Reply-To" header, pointing to the saved Message-ID.
My code looks like this:
Message message = new CustomMessage(session, parentMessageId);
message.setFrom(new InternetAddress("from#mycompany.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("to#customer.com"));
message.setSubject("Issue " + id + " " + actionPerformed);
message.setText(content);
message.saveChanges();
Transport.send(message);
Class CustomMessage looks like this:
public class CustomMessage extends MimeMessage {
private String inReplyTo;
public CustomMessage(Session session, String inReplyTo) {
super(session);
this.inReplyTo = inReplyTo;
}
#Override
public void saveChanges() throws MessagingException {
if (inReplyTo != null) {
// This messageID is something like "<51228289.0.1459073465571.JavaMail.admin#mycompany.com>" including <>
setHeader("In-Reply-To", inReplyTo);
}
}
}
The problem is the email is sent, but is not grouped in threads. I have noticed that they are grouped correctly if they have the same subject, but I need different subjects for every email.
Is this actually possible with different subjects? Do I need to use a different strategy?
Thanks
It depends on the "threading" algorithm used by whichever mail reader is being used. As the creator of the messages you don't have absolute control over how they're displayed.