Created sendgrid email template, how to call it from Java - sendgrid

I have created email template in sendgrid - with substitutable values;
I get the JSON payload (contains substitute values) for processing email from rabbitMQ queue. My question is how to call the sendgrid email template from Java?

I found the solution, the way to call sendgrid template and email through sendgrid as below:
SendGrid sendGrid = new SendGrid("username","password"));
SendGrid.Email email = new SendGrid.Email();
//Fill the required fields of email
email.setTo(new String[] { "xyz_to#gmail.com"});
email.setFrom("xyz_from#gmail.com");
email.setSubject(" ");
email.setText(" ");
email.setHtml(" ");
// Substitute template ID
email.addFilter(
"templates",
"template_id",
"1231_1212_2323_3232");
//place holders in template, dynamically fill values in template
email.addSubstitution(
":firstName",
new String[] { firstName });
email.addSubstitution(
":lastName",
new String[] { lastName });
// send your email
Response response = sendGrid.send(email);

This is my working soloution .
import com.fasterxml.jackson.annotation.JsonProperty;
import com.sendgrid.*;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class MailUtil {
public static void main(String[] args) throws IOException {
Email from = new Email();
from.setEmail("fromEmail");
from.setName("Samay");
String subject = "Sending with SendGrid is Fun";
Email to = new Email();
to.setName("Sam");
to.setEmail("ToEmail");
DynamicTemplatePersonalization personalization = new DynamicTemplatePersonalization();
personalization.addTo(to);
Mail mail = new Mail();
mail.setFrom(from);
personalization.addDynamicTemplateData("name", "Sam");
mail.addPersonalization(personalization);
mail.setTemplateId("TEMPLATE-ID");
SendGrid sg = new 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;
}
}
private static class DynamicTemplatePersonalization extends Personalization {
#JsonProperty(value = "dynamic_template_data")
private Map<String, String> dynamic_template_data;
#JsonProperty("dynamic_template_data")
public Map<String, String> getDynamicTemplateData() {
if (dynamic_template_data == null) {
return Collections.<String, String>emptyMap();
}
return dynamic_template_data;
}
public void addDynamicTemplateData(String key, String value) {
if (dynamic_template_data == null) {
dynamic_template_data = new HashMap<String, String>();
dynamic_template_data.put(key, value);
} else {
dynamic_template_data.put(key, value);
}
}
}
}

Here is an example from last API spec:
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 = "I'm replacing the subject tag";
Email to = new Email("test#example.com");
Content content = new Content("text/html", "I'm replacing the <strong>body tag</strong>");
Mail mail = new Mail(from, subject, to, content);
mail.personalization.get(0).addSubstitution("-name-", "Example User");
mail.personalization.get(0).addSubstitution("-city-", "Denver");
mail.setTemplateId("13b8f94f-bcae-4ec6-b752-70d6cb59f932");
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;
}
}
}
https://github.com/sendgrid/sendgrid-java/blob/master/USE_CASES.md

Recently Sendgrid upgraded the Maven version v4.3.0 so you don't have to create additional classes for dynamic data content. Read more from this link https://github.com/sendgrid/sendgrid-java/pull/449

If you're doing a spring-boot maven project, You'll need to add the sendgrid-java maven dependency in your pom.xml. Likewise, in your application.properties file under resource folder of the project, add SENDGRID API KEY AND TEMPLATE ID under attributes such as spring.sendgrid.api-key=SG.xyz and templateId=d-cabc respectively.
Having done the pre-setups. You can create a simple controller class as the one given below:
Happy Coding!
#RestController
#RequestMapping("/sendgrid")
public class MailResource {
private final SendGrid sendGrid;
#Value("${templateId}")
private String EMAIL_TEMPLATE_ID;
public MailResource(SendGrid sendGrid) {
this.sendGrid = sendGrid;
}
#GetMapping("/test")
public String sendEmailWithSendGrid(#RequestParam("msg") String message) {
Email from = new Email("bijay.shrestha#f1soft.com");
String subject = "Welcome Fonesal Unit to SendGrid";
Email to = new Email("birat.bohora#f1soft.com");
Content content = new Content("text/html", message);
Mail mail = new Mail(from, subject, to, content);
mail.setReplyTo(new Email("bijay.shrestha#f1soft.com"));
mail.setTemplateId(EMAIL_TEMPLATE_ID);
Request request = new Request();
Response response = null;
try {
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
response = sendGrid.api(request);
System.out.println(response.getStatusCode());
System.out.println(response.getBody());
System.out.println(response.getHeaders());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
return "Email was successfully sent";
}
}

This is based on verision com.sendgrid:sendgrid-java:4.8.3
Email from = new Email(fromEmail);
Email to = new Email(toEmail);
String subject = "subject";
Content content = new Content(TEXT_HTML, "dummy value");
Mail mail = new Mail(from, subject, to, content);
// Using template to send Email, so subject and content will be ignored
mail.setTemplateId(request.getTemplateId());
SendGrid sendGrid = new SendGrid(SEND_GRID_API_KEY);
Request sendRequest = new Request();
sendRequest.setMethod(Method.POST);
sendRequest.setEndpoint("mail/send");
sendRequest.setBody(mail.build());
Response response = sendGrid.api(sendRequest);
You can also find fully example here:
Full Email object Java example

Related

get files from IFormFile for email attachment

I have an upload controller
// Multiple files upload
[HttpPost("upload/multiple")]
public IActionResult Multiple(IFormFile[] files)
{
try
{
// Put your code here
return StatusCode(200);
}
catch (Exception ex)
{
return StatusCode(500, ex.Message);
}
}
I am trying to use the IFormFile to get files for email attachments using MailKit
This is my email code
private async Task SendEmail()
{
try
{
// create email message
var email = new MimeMessage();
email.From.Add(MailboxAddress.Parse(sender));
email.To.Add(MailboxAddress.Parse(receiver));
email.Subject = emailsubject;
var multipart = new Multipart("mixed");
multipart.Add(new TextPart(TextFormat.Html) { Text = emailMessage });
foreach (var attachment in files)
{
var content = new MemoryStream();
attachment.CopyTo(content);
content.Position = 0;
var contentType = ContentType.Parse(attachment.ContentType);
var part = new MimePart(contentType.MimeType)
{
FileName = Path.GetFileName(attachment.FileName),
ContentTransferEncoding = ContentEncoding.Base64,
Content = new MimeContent(content),
};
multipart.Add(part);
}
email.Body = multipart;
//email.Body = new TextPart(TextFormat.Html) { Text = emailMessage};
// send email
using var smtp = new SmtpClient();
smtp.Connect(outgoingServer, outgoingPort, SecureSocketOptions.Auto);
smtp.Authenticate(userName, userPassword);
smtp.Send(email);
smtp.Disconnect(true);
}
catch (Exception ex)
{
NotificationService.Notify(NotificationSeverity.Error, "Send Email Error!", ex.Message, 7000);
}
}
}
This generates an error on the 'files' variable
"The name 'files' does not exist in the current content.
Can someone tell me what I am missing to pull the information from the controller for 'files'???
Here, in the Async Task SendEmail task, we have to set the parameter of type IFormFile like below,
private async Task sendEmail(IFormFile file)
Here is the Controller Code,
[HttpPost("send")]
public async Task<IActionResult> SendMail(IFormFile file)
{
try
{
await mailService.sendEmailAsync(file);
return Ok("Mail Sent!");
}
catch (Exception ex)
{
throw;
}
}
And We can't get IFormFile[] directly and pass it to the sendEmail method as a parameter. Instead we can create the model class with public List<IFormFile>? attachments{get;set;} and send the instance of the model class as a parameter to the sendEmail method.

How to send email with no-reply in spring-boot application

I'm trying to send emails to project managers whenever there is a change in their project staffing. For this i want to send an email from no-reply#example.com, how can i achieve this using spring boot?
Thanks in advance for the suggestions and answers.
Tried something like this:
#RequestMapping(value = "/sendEmail", method = { RequestMethod.GET }, produces = { "application/json" })
public ResponseEntity<CustomResponse> sendEmail() {
LOG.debug("Start sendEmail with data, toAddress");
HttpHeaders httpHeaders = commonUtil.setHeaders();
HttpStatus httpStatus = HttpStatus.OK;
CustomResponse customResp = new CustomResponse();
String description;
try {
String to = "bmanikanta415#gmail.com";
String from = "no-reply#example.com";
Properties props = System.getProperties();
Session session = Session.getDefaultInstance(props, null);
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
msg.setSubject("Your Example.com account has been activated");
msg.setText("This is a test");
Transport.send(msg);
description = Constants.SUCCESS;
customResp = commonUtil.getCustomResponse(httpStatus, description, description);
} catch (
Exception e) {
LOG.error("Exception in sendEmail: {}", e);
description = Constants.FAILED;
customResp = commonUtil.getCustomResponse(httpStatus, description, description);
}
ResponseEntity<CustomResponse> responseEntity = new ResponseEntity<CustomResponse>(customResp, httpHeaders,
httpStatus);
LOG.debug("End sendEmail with return data: {}", responseEntity);
return responseEntity;
}

how can I key rotate for google cloud storage service account?

I have written code for accessing GCS bucket to store files thru API in java which takes JSON credential file. I have created that JSON file from google console. I need to automate the JSON file or key rotation for every 90 days. How to regenerate/rotate that JSON file? I am a newbie to GCS.
import java.io.IOException;
import java.security.GeneralSecurityException;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpMethods;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.iam.v1.Iam;
import com.google.api.services.iam.v1.IamRequest;
import com.google.api.services.iam.v1.IamRequestInitializer;
import com.google.api.services.iam.v1.model.CreateServiceAccountKeyRequest;
public class TestServiceAccount {
public static void main(String[] args) {
// TODO Auto-generated method stub
//ServiceAccountKey key = new ServiceAccountKey();
try {
System.out.println("created");
String KEY = "AIzaSyDjHg2u4bwfvncb_YwdjJC_vUPRYLW5Sh8";
IamRequestInitializer req = new IamRequestInitializer(KEY);
HttpTransport transport;
transport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = new JacksonFactory();
Iam iam = new Iam(transport,jsonFactory,new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) {
httpRequest.setConnectTimeout(0);
httpRequest.setReadTimeout(0);
}
});
//https://iam.googleapis.com/v1/projects/newsampleproject/serviceAccounts/NewServiceAccount/keys
MyIamRequest<String> request = new MyIamRequest<String>(
iam, HttpMethods.POST, "/v1/projects/newsampleproject/serviceAccounts/NewServiceAccount/keys", String.class, String.class);
req.initialize(request);
System.out.println(req.getKey());
req.initializeJsonRequest(request);
System.out.println(req.getUserIp());
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
//req.initializeJsonRequest(request);
}
public static HttpRequestFactory createRequestFactory(HttpTransport transport) {
return transport.createRequestFactory(new HttpRequestInitializer() {
public void initialize(HttpRequest request) throws IOException {
}
});
}
}
This what I have written to call the API But i am not sure if this is the way to call it.
try this solution, it worked for me
private static void createNewKey(IamRequestInitializer req) throws IOException, GeneralSecurityException {
Iam iam = jsonAuthentication();
CreateServiceAccountKeyRequest keyRequest = new CreateServiceAccountKeyRequest();
keyRequest.setKeyAlgorithm(KEY_ALGO);
String account = SERVICE_ACCOUNT_URL + SERVICE_ACCOUNT_EMAIL;
iam.projects().serviceAccounts().keys().create(account, keyRequest);
String requestString = BASE_URL + SERVICE_ACCOUNT_EMAIL + KEY;
ServiceAccountKey result = getServiceAccountKey(req, iam, requestString);
String jsonKey = new String(result.decodePrivateKeyData());
System.out.println(jsonKey);
JsonFileUtil.createFile(JSON_KEY_FILE_NAME, jsonKey);
}
private static <T> T getServiceAccountKey(IamRequestInitializer req, Iam iam, String requestString)
throws IOException {
MyIamRequest<String> request = new MyIamRequest<String>(iam, HttpMethods.POST, requestString, String.class,
ServiceAccountKey.class);
request.setKey(API_KEY);
request.setFields(
"keyAlgorithm,name,privateKeyData,privateKeyType,publicKeyData,validAfterTime,validBeforeTime");
req.initializeJsonRequest(request);
System.out.println(request.getRequestHeaders());
return (T) request.execute();
}
If you're using a JSON credential file, you are acting as some particular service account which is a member of your project and has access to the files.
Service accounts can be programmatically controlled for exactly this sort of use case. The IAM Service Account API controls service accounts, and the two methods you want for key rotation are serviceAccount.keys.create() and serviceAccount.keys.delete().
The result of the create() call (if you pass in the private key type TYPE_GOOGLE_CREDENTIALS_FILE), will be a new, valid JSON credential file for your service account.
#user7049946
ServiceAccountKey response = getServiceAccountKey(req, iam, requestString);
CreateNewJson.createFile("NEW_JSON_KEY_FILE_NAME", new String(response.decodePrivateKeyData()));
create new class to convert that conent into new file.
public class CreateNewJson {
public static void createFile(String filename, String content) throws IOException {
FileOutputStream fileOutputStream = null;
File file;
file = new File(filename);
fileOutputStream = new FileOutputStream(file);
if (!file.exists()) {
file.createNewFile();
}else{
file.delete();
file.createNewFile();
}
byte[] contentInBytes = content.getBytes();
fileOutputStream.write(contentInBytes);
fileOutputStream.flush();
fileOutputStream.close();
System.out.println("File Created");
}
}

Autodiscover cannot process the given e-mail address. Only mailboxes and contacts are allowed

While sending email using ExchangeService is throwing Exception as Message is: "The Autodiscover service returned an error." and "Autodiscover cannot process the given e-mail address.
Only mailboxes and contacts are allowed".
public void SendEmail(string to, string cc, string subject, string body, string emailType)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
service.Credentials = new WebCredentials("test#outlook.com", "test");
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.AutodiscoverUrl("test#outlook.com", RedirectionUrlValidationCallback);
EmailMessage email = new EmailMessage(service);
email.ToRecipients.Add(to);
email.CcRecipients.Add(cc);
email.Subject = subject;
email.Body = new MessageBody(body);
email.Send();
}
private static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
if (redirectionUri.Scheme == "https")
{
result = true;
}
return true;
}
the above code is working fine with "...#microsoft.com" but not working with "...outlook.com"
can anyone help to resolve issue.

How do I write an email body to a text file using the Java Gmail API

i'm trying to access my Gmail account using Java Gmail API then access the body of the first Email and then save it into text file using this path in my computer D:\Email , so any suggestion ? i have tried so many examples such as using saveFile but none of them worked for me !
NOTE: i want only to save the body of the Email
package ReadingEmail;
import java.util.*;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Store;
//===================================================================================
public class ReadingEmail {
public static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
try {
Session session = Session.getInstance(props, null);
Store store = session.getStore();
System.out.println("enter your email");
String email= input.nextLine();
System.out.println("enter your password");
String pass= input.nextLine();
store.connect("imap.gmail.com", email, pass); //connect to email
Folder inbox = store.getFolder("INBOX");// go to index
inbox.open(Folder.READ_ONLY); // open index
//==============================================================================================
int messageCount = inbox.getMessageCount();// line 20,21 show the number of emails
System.out.println("Total Messages" + messageCount);
int Message1 = messageCount;
int Message2 = Message1 -1 ;
Message msg1= inbox.getMessage(messageCount);
Message msg2= inbox.getMessage(Message2);
Address[] in1 = msg1.getFrom();
for (Address address1 : in1) {}
//================================================================================
Message msg = inbox.getMessage(inbox.getMessageCount());
Address[] in = msg.getFrom();
for (Address address : in) {
}
Multipart mp = (Multipart) msg.getContent();
BodyPart bp = mp.getBodyPart(0);
System.out.println("CONTENT:" + bp.getContent());
}
catch (Exception ex) // wrong password
{ System.out.println("the email or password is wrong "); }
}
}
Are you getting any error? Right now I am unable to see any code to save to a file.
Also when you use System.out.println("CONTENT:" + bp.getContent()); are you able to print the text to console or not?