I'm trying to create a draft with an attachment in Java using Gmail API.
Creating a basic draft works, so I've eliminated any permission problem. I've used code here as an inspiration but cannot get it to work.
Here's what I did so far:
public String generateGmailDraft(EmailRequestDto emailRequestDto, String quoteId)
throws MessagingException, IOException, GeneralSecurityException {
// The attachment is a PDF file
AttachmentDto lastQuoteData = getLastQuotePdfData(quoteId);
MimeMessage email = createMimeMessage(emailRequestDto, lastQuoteData);
Message messageWithEmail = createMessageWithEmail(email);
Draft draft = new Draft();
draft.setMessage(messageWithEmail);
// this works
Gmail gmail = gmail(googleGmailCredentialProperties);
log.debug("attempting to send mail");
draft = gmail.users().drafts().create(emailRequestDto.getFrom(), draft).execute();
log.debug("Draft id: {}", draft.getMessage().getId());
log.debug(draft.toPrettyString());
return draft.getMessage().getId();
}
From Google example, I created a MIME message, but this is probably where the problem lies:
/**
* Create a MimeMessage using the parameters provided
* @return the MimeMessage to be used to send email
* @throws MessagingException
*/
private MimeMessage createMimeMessage(EmailRequestDto requestDto, AttachmentDto attachment)
throws MessagingException, IOException {
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
MimeMessage email = new MimeMessage(session);
email.setFrom(new InternetAddress(requestDto.getFrom()));
email.addRecipient(javax.mail.Message.RecipientType.TO, ew InternetAddress(requestDto.getTo()));
email.setSubject(requestDto.getSubject());
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setHeader("Content-Type", "multipart/alternative");
messageBodyPart.setText(requestDto.getBody()); // Setting the actual message
// Create a multipart message and set text message part
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// Try to add an attachment
MimeBodyPart attachmentBP = new MimeBodyPart();
attachmentBP.setFileName(attachment.fileName);
ByteArrayOutputStream baos = attachmentToByteArrayOutputStream(attachment.file);
DataSource dataSrc = new ByteArrayDataSource(baos.toByteArray(), "application/pdf");
attachmentBP.setDataHandler(new DataHandler(dataSrc));
multipart.addBodyPart(attachmentBP);
// Send the complete message parts
email.setContent(multipart);
return email;
}
This private class hopefully provides everything needed for the attachment, when used, all private fields are correctly filled.
/**
AttachmentDTO returns everything needed to create an attachment
- file
- mimeype
- filename
- inputstream : used because file can come from different sources in the app.
*/
private static final class AttachmentDto {
private final InputStream inputStream;
private final String fileName;
private File file;
private String mimeType;
private AttachmentDto(InputStream inputStream, String fileName) {
this.inputStream = inputStream;
this.fileName = fileName;
File outputFile = new File(fileName);
try (OutputStream out = new FileOutputStream(outputFile)) {
IOUtils.copy(inputStream, out);
file = outputFile;
mimeType = Files.probeContentType(outputFile.toPath());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public InputStream getInputStream() {
return inputStream;
}
public String getFileName() {
return fileName;
}
public File getFile() {
return file;
}
public String getMimeType() {
return mimeType;
}
}
Current state:
gmail.users().drafts().create(emailRequestDto.getFrom(), draft).execute();
and never returnsfollowing the link above, I also tried to encode the attachment as Base64, then use
public Gmail.Users.Drafts.Create create( String userId, Draft content, AbstractInputStreamContent mediaContent) throws java.io.IOException
which is, I suppose, the counterpart to use when you have an attachment.
When I use this, draft gets created in my mailbox but without the attachment.
Any help appreciated, thank you.
Try something similar to this:
private MimeMessage createEmailWithAttachment(String to,
String subject,
String bodyText,
File file) throws MessagingException, IOException {
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
MimeMessage email = new MimeMessage(session);
email.addRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress(to));
email.setSubject(subject);
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setContent(bodyText, "text/plain");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(mimeBodyPart);
mimeBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(file);
mimeBodyPart.setDataHandler(new DataHandler(source));
mimeBodyPart.setFileName(file.getName());
multipart.addBodyPart(mimeBodyPart);
email.setContent(multipart);
return email;
}