Basic example from Sendgrids documentation:
// using SendGrid's Java Library
// https://github.com/sendgrid/sendgrid-java
import com.sendgrid.*;
import java.io.IOException;
public class Example {
public static void main(String[] args) throws IOException {
Email from = new Email("test#example.com");
String subject = "Sending with SendGrid is Fun";
Email to = new Email("test#example.com");
Content content = new Content("text/plain", "and easy to do anywhere, even with Java");
Mail mail = new Mail(from, subject, to, content);
SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY"));
Request request = new Request();
try {
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
Response response = sg.api(request);
System.out.println(response.getStatusCode());
System.out.println(response.getBody());
System.out.println(response.getHeaders());
} catch (IOException ex) {
throw ex;
}
}
}
I am using 4.9.3 version (java 8 still), should that Request be com.sendgrid.Request? Cause seems that Request is not in that package?
Related
I am currently in the process of integrating MailGun into one of my applications. For my use cases I need to be able to send out attachments. So far, I have been able to send out attachments just fine but my problem is that I am unable to specify the attachment's name. Their documentation found here specifies that the attachment part should be added when including attachment, but does not state how to specify the file's name.
For reference I am using Spring's RestTemplate as my client and I am reading the file as a base64 encoded string which is then trasnformed into a ByteArrayResource. For reference my code is this:
#Override
public EmailDocument sendEmail(EmailDocument email) {
var properties = propProvider.findFor(email.getCompany());
var parts = new LinkedMultiValueMap<String, Object>();
parts.add("from", email.getFrom());
parts.add("to", toCommaString(email.getTo()));
if (!email.getCc().isEmpty()) {
parts.add("cc", toCommaString(email.getCc()));
}
if (!email.getBcc().isEmpty()) {
parts.add("bcc", toCommaString(email.getBcc()));
}
parts.add("subject", email.getSubject());
if (email.getIsHtml()) {
parts.add("html", email.getBody());
} else {
parts.add("text", email.getBody());
}
email.getAttachments().forEach(attachment -> {
var decoded = Base64.getDecoder().decode(attachment.getBytes(StandardCharsets.UTF_8));
parts.add("attachment", new ByteArrayResource(decoded));
});
var header = headerProvider.createHeader("api", properties.getApiKey(), inferMediaType(email));
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(parts, header);
try {
var response = restTemplate.exchange(createDomain(properties.getDomain()), HttpMethod.POST, request, MailGunApiResponse.class);
log.info("Got the following MailGun response {}", response);
if (!response.getStatusCode().is2xxSuccessful()) {
email.setFailureReason(Optional.ofNullable(response.getBody()).map(MailGunApiResponse::getMessage).orElse(null));
email.setRetries(email.getRetries() + 1);
email.setFailed(isFailed(email));
} else {
email.setSent(true);
}
} catch (Exception e) {
log.error("An error has occurred while attempting to send out email {}", email, e);
email.setFailureReason(e.getMessage());
email.setRetries(email.getRetries() + 1);
email.setFailed(isFailed(email));
}
return email;
}
Does anyone know how to specify a filename for the attachment?
I am trying to update my API Code from Sendgrid v2, to the actual Sendgrid v3, so my code used to look like this:
public void sendCreatedUserEmail(User user) {
Email from = new Email(FROM);
from.setName(EMAIL_NAME);
String subject = "Hello" + user.getName();
Email to = new Email(user.getEmail());
Content content = new Content("text/html", "Something");
Mail mail = new Mail(from, subject, to, content);
mail.personalization.get(0).addSubstitution("{name1}", user.getName());
mail.personalization.get(0).addSubstitution("{name2}", user.getName());
mail.setTemplateId(USER_TEMPLATE_ID);
SendGrid sg = new SendGrid(SENDGRID_API_KEY);
Request request = new Request();
try {
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
Response response = sg.api(request);
} catch (IOException ex) {
logger.error(ex);
}
}
After some hours of research I changed for v3 to this:
(I separeted everthing for a cleaner view)
public void sendCreatedUserEmail(User user) {
Mail mail = new Mail();
Email from = new Email();
from.setName(EMAIL_NAME);
from.setEmail(FROM);
mail.setFrom(from);
String subject = "Hello, " + user.getName();
mail.setSubject(subject);
Personalization personalization = new Personalization();
Email to = new Email();
to.setEmail(user.getEmail());
to.setName(user.getName());
personalization.addTo(to);
personalization.setSubject(subject);
personalization.addSubstitution("{name2}",user.getName());
personalization.addSubstitution("{name1}",user.getName());
mail.addPersonalization(personalization);
Content content = new Content();
content.setType("text/html");
content.setValue("Something");
mail.addContent(content);
mail.setTemplateId(NEW_USER_TEMPLATE_ID);
SendGrid sg = new SendGrid(SENDGRID_API_KEY);
Request request = new Request();
try {
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
Response response = sg.api(request);
System.out.println(response.getStatusCode());
System.out.println(response.getBody());
System.out.println(response.getHeaders());
} catch (IOException ex) {
logger.error(ex);
}
}
I am getting the following error:
ERROR ROOT - java.io.IOException: Request returned status Code 400Body:{"errors":[{"message":"Substitutions may not be used with dynamic templating","field":"personalizations.0.substitutions","help":"http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#message.personalizations.substitutions"}]}
And I really don't know how to proceed! I've been reading the sendgrid documentation but I couldn't get it.
Some details that might help
- Java8 is the language
- MAVEN for dependencies
- IntelliJ for the IDE
Sorry for the possible mistakes, it's my first post and English is not my main language. Thank you!
V3 of the Sendgrid API uses Dynamic Template Data instead of substitutions.
Try this instead of using addSubstitution:
personalization.addDynamicTemplateData("{name2}",user.getName());
personalization.addDynamicTemplateData("{name1}",user.getName());
Sources:
https://github.com/sendgrid/sendgrid-java/blob/9bc569cbdb908dba609ed0d9d2691dff319ce155/src/main/java/com/sendgrid/helpers/mail/objects/Personalization.java
https://sendgrid.com/docs/ui/sending-email/how-to-send-an-email-with-dynamic-transactional-templates/
Try:
personalization.addDynamicTemplateData("name2",user.getName());
personalization.addDynamicTemplateData("name1",user.getName());
I followed Google's information to send an email from App Engine via SendGrid. This is working fine using the Java library for SendGrid and the provided example code:
import packageName.Sendgrid;
Sendgrid mail = new Sendgrid("<sendgrid_username>","<sendgrid_password>");
mail.setTo("foo#bar.com")
.setFrom("me#bar.com")
.setSubject("Subject goes here")
.setText("Hello World!")
mail.send();
But now I need to attach an file. How can this be done? I cannot find an addAttachment-function or something like that in the sendgrid-google-java library.
I just use the SendGrid Java API on appengine, not a specific google one.
Here's an example:
import com.sendgrid.*;
public class SendGridExample {
public static void main(String[] args) {
SendGrid sendgrid = new SendGrid("SENDGRID_APIKEY");
SendGrid.Email email = new SendGrid.Email();
email.addTo("test#sendgrid.com");
email.setFrom("you#youremail.com");
email.setSubject("Sending with SendGrid is Fun");
email.setHtml("and easy to do anywhere, even with Java");
SendGrid.Response response = sendgrid.send(email);
}
}
https://sendgrid.com/docs/Integrate/Code_Examples/v2_Mail/java.html
You can add attachments to this email object using either one of these 3 functions:
public Email addAttachment(String name, File file) throws IOException, FileNotFoundException {
return this.addAttachment(name, new FileInputStream(file));
}
public Email addAttachment(String name, String file) throws IOException {
return this.addAttachment(name, new ByteArrayInputStream(file.getBytes()));
}
public Email addAttachment(String name, InputStream file) throws IOException {
this.attachments.put(name, file);
return this;
}
Sending email from GAE using sendgrid-java is working as suggested by Serge Hendrickx.
Just for reference, here is the code I ended up using (with the latest sendgrid-java.jar):
public static Mail buildAttachmentEmailExample(String fileName, String base64EncodedFileContent, String contentType) throws IOException {
Mail mail = new Mail();
Personalization pers = new Personalization();
Email from = new Email("test#example.com");
mail.setFrom(from);
String subject = "Hello World from the SendGrid Java Library";
pers.setSubject(subject);
Email to = new Email("test#example.com");
pers.addTo(to);
Email cc = new Email("test2#example.com");
pers.addCc(cc);
Content content = new Content("text/plain", "some text here");
mail.addContent(content);
Attachments attachments = new Attachments();
attachments.setContent(base64EncodedFileContent);
attachments.setType(contentType);
attachments.setFilename(fileName);
mail.addAttachments(attachments);
mail.addPersonalization(pers);
return mail;
}
public static void sendMail(Mail mail) throws IOException {
SendGrid sg = new SendGrid("SENDGRID_API_KEY");
Request request = new Request();
try {
request.method = Method.POST;
request.endpoint = "mail/send";
request.body = mail.build();
Response response = sg.api(request);
System.out.println(response.statusCode);
System.out.println(response.body);
System.out.println(response.headers);
} catch (IOException ex) {
throw ex;
}
}
public static void test() throws IOException {
Mail mail = buildAttachmentEmailExample("test.txt", "WW91IGhhdmUgdG9vIG11Y2ggdGltZSE=", "text/plain");
sendMail(mail);
}
The code is based on the examples at https://github.com/sendgrid/sendgrid-java/blob/master/examples/helpers/mail/Example.java and utilizes the newer SendGrid v3 API.
service code:
#RequestMapping(value="/uploadFile", method=RequestMethod.POST, consumes = "multipart/form-data")
public String uploadFile(#RequestParam("file") MultipartFile file,#RequestParam("filePath") String filePath){
//logic here
}
Part of the client code:
public static synchronized String responseOfPost(String restUrl, FileSystemResource file,String filePath) {
PostMethod post = new PostMethod(restUrl);
HttpClient client = new HttpClient();
post.setParameter("filePath", filePath);
try {
Part[] parts = {new FilePart("file",file.getFile())};
post.addRequestHeader("Content-Type", "multipart/form-data; boundary=Endedlogging");
if (file != null) {
post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
}
client.executeMethod(post);
String response = post.getResponseBodyAsString();
} catch (final IOException e) {
e.printStackTrace();
}
return null;
}
this is the error I am getting:
org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:251)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:96)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:78)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
How can I pass multipart file("file") and filePath("filePath") to POST method in client code? NOT FROM UI
I'm also getting the exception like FileNotFoundException with nearly same code as your's.So can you try with this change,it maybe helpful.
Part[] parts = {new FilePart(file.getName(),file)};
I'm having some issues running a web app which is basically a URL shortener.
The server have a functionality that allows to upload a CSV file with a list of URLs to short. The code bellow is a method that takes a CSV file from a queue, it reads the file and shorts the URLs in it. The problem comes when I try to send a post request to on of the controllers in my server. The exception that appears is the following:
javax.ws.rs.ProcessingException: HTTP 500 Internal Server Error
Here is the code of the method I mentioned:
while(true){
QueueObject qo = csvQueue.take();
copyFile(qo.getFile());
File f = new File("temp");
Scanner sc = new Scanner(f);
sc.useDelimiter(",|\\s");
Client client = ClientBuilder.newClient();
while(sc.hasNext()){
String url = sc.next();
ResponseEntity<ShortURL> res = shortener(url, null, null, null, null, null);
if(res!=null && ((res.getStatusCode()).toString()).equals("400")){
String stat = url + " : Failed";
UpdateMessage um = new UpdateMessage(stat, qo.getUser());
Response response = client.target("http://localhost:8080/urlUploads")
.request(MediaType.APPLICATION_JSON)
.post(Entity.entity(um, MediaType.APPLICATION_JSON));
}
else{
String stat = url + " : Success";
UpdateMessage um = new UpdateMessage(stat, qo.getUser());
Response response = client.target("http://localhost:8080/urlUploads")
.request(MediaType.APPLICATION_JSON)
.post(Entity.entity(um, MediaType.APPLICATION_JSON));
}
}
f.delete();
}
As I said, the problem is on this specific request (both are basically the same):
Response response = client.target("http://localhost:8080/urlUploads")
.request(MediaType.APPLICATION_JSON)
.post(Entity.entity(um, MediaType.APPLICATION_JSON));
The controller I'm trying to reach is this one:
#Controller
public class WebSocketController {
private SimpMessagingTemplate template;
private static final Logger logger = LoggerFactory.getLogger(WebSocketController.class);
#Autowired
public WebSocketController(SimpMessagingTemplate template) {
this.template = template;
}
#RequestMapping(value="/urlUploads", method=RequestMethod.POST)
public void greet(UpdateMessage update) {
this.template.convertAndSendToUser(update.getUser(), "/sockets/urlUploads", update.getStatus());
}
}