Reputation: 41
How to send a calendar invite through java , so that we don't need to open .ics file and add to calendar. When we send a mail to outlook, it should attach as direct meeting invite , i don't want to open the .ics file and add explicitly to calendar. Is it possible to do it in java or not. Even when we use ICal4J also these .ics file is not adding automatically to the calendar.
public void send(Appointment appointment, String host) throws Exception {
try {
Properties prop = new Properties();
prop.put("mail.smtp.host", host);
prop.put("mail.smtp.port", "25");
prop.put("mail.smtp.auth", "false");
prop.put("mail.smtp.starttls.enable", "false");
Session session = Session.getDefaultInstance(prop, null);
// Define message
MimeMessage message = new MimeMessage(session);
String toMa = StringUtils.getCommaDelimitedStringfromStringList(appointment.getTo());
String ccMa = null;
if(Objects.nonNull(appointment.getCc())) {
ccMa = StringUtils.getCommaDelimitedStringfromStringList(appointment.getCc());
}
message.setFrom(new InternetAddress(appointment.getFrom()));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toMa));
message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(ccMa));
message.setSubject(appointment.getSubject());
message.setHeader("Content-class", "urn:content-classes:calendarmessage");
String content = getBufferString(appointment);
// Create the message part
BodyPart messageBodyPart = new MimeBodyPart();
// Fill the message
messageBodyPart.setHeader("Content-class", "urn:content- classes:calendarmessage");
messageBodyPart.setContent(appointment.getContent(),"mailBody");
messageBodyPart.setDataHandler(new DataHandler(new ByteArrayDataSource(content, "text/calendar; charset=utf-8; method=REQUEST'")));// very
// important
// new
MimeBodyPart bc = new MimeBodyPart();
bc.setContent(appointment.getContent(),"text/html");
BodyPart messageBody = bc;
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBody);
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);
// send message
Transport.send(message);
}
catch (Exception ex) {
log.error("exception", ex);
}
}
private String getBufferString(Appointment appointment) {
StringBuffer sb = new StringBuffer();
StringBuffer buffer = sb.append("BEGIN:VCALENDAR\n"+
"PRODID:-Asset View 2.0\n"+
"VERSION:2.0\n" +
"METHOD:REQUEST\n" +
"BEGIN:VEVENT\n" +
"DTSTAMP:"+extracted(FORMATED_DATE_TIME, 0, null)+"\n" +
"LOCATION:"+appointment.getLocation()+"\n" +
extractDstartDend(appointment)+
createRecurring(appointment)+"\n"+
"UID:"+UUID.randomUUID().toString()+"\n" +
"DESCRIPTION:"+appointment.getContent().substring(3, appointment.getContent().length() - 4)+"\n" +
"SUMMARY:"+appointment.getSubject()+"\n" +
"ORGANIZER:MAILTO:"+appointment.getFrom()+"\n" +
"X-MS-OLK-FORCEINSPECTOROPEN:TRUE\n"+
"X-WR-RELCALID:{0000002E-9CDF-9CE8-AD4C-66FC0A5A25F7}\n"+
String.format("ATTENDEE;CN=%s;RSVP=TRUE:mailto:%s",
appointment.getTo().stream().findFirst().orElse(null),
appointment.getTo().stream().findFirst().orElse(null))+"\n"+
"X-MICROSOFT-CDO-BUSYSTATUS:FREE"+"\n"+
"BEGIN:VALARM\n" +
"ACTION:DISPLAY\n" +
"DESCRIPTION:Reminder\n" +
"TRIGGER:-P1D\n" +
"END:VALARM\n" +
"END:VEVENT\n" +
"END:VCALENDAR");
return buffer.toString();
}
Upvotes: 1
Views: 1962
Reputation: 41
I found the missing piece in my code and removed unneccesary code, which is most important. "method=REQUEST"
public void send(Appointment appointment, String host) throws Exception {
try {
Properties prop = new Properties();
prop.put("mail.smtp.host", host);
Session session = Session.getDefaultInstance(prop, null);
// Define message
MimeMessage message = new MimeMessage(session);
message.addHeaderLine("method=REQUEST");
message.addHeaderLine("charset=UTF-8");
message.addHeaderLine("component=VEVENT");
String toMa = StringUtils.getCommaDelimitedStringfromStringList(appointment.getTo());
String ccMa = null;
if (Objects.nonNull(appointment.getCc())) {
ccMa = StringUtils.getCommaDelimitedStringfromStringList(appointment.getCc());
message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(ccMa));
}
message.setFrom(new InternetAddress(appointment.getFrom()));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toMa));
message.setSubject(appointment.getSubject());
message.setHeader("Content-class", "urn:content-classes:calendarmessage");
String content = getBufferString(appointment);
// Create the message part
BodyPart messageBodyPart = new MimeBodyPart();
// Fill the message
messageBodyPart.setHeader("Content-Class", "urn:content- classes:calendarmessage");
messageBodyPart.setHeader("Content-ID", "calendar_message");
messageBodyPart.setDataHandler(new DataHandler(new ByteArrayDataSource(content, "text/calendar;method=REQUEST")));// very
// important
// new
MimeBodyPart bc = new MimeBodyPart();
bc.setContent(appointment.getContent(), "text/html");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(bc);
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);
// send message
Transport.send(message);
}
catch (Exception ex) {
log.error("exception", ex);
}
}
private String getBufferString(Appointment appointment) {
StringBuilder sb = new StringBuilder();
StringBuilder buffer = sb.append(
"BEGIN:VCALENDAR\n"
+ "PRODID: Asset View 2.0\n"
+ "VERSION:2.0\n"
+ "METHOD:REQUEST\n"
+ "BEGIN:VEVENT\n"
+ "DTSTAMP:" + extracted(FORMATED_DATE_TIME, 0, null) + "\n"
+ "LOCATION:" + appointment.getLocation() + "\n"
+ extractDstartDend(appointment)
+ createRecurring(appointment)
+ "UID:" + UUID.randomUUID().toString() + "\n"
+ "DESCRIPTION:"+ appointment.getContent() +"\n"
+ "X-ALT-DESC;FMTTYPE=text/html:"+ appointment.getContent() + "\n"
+ "SUMMARY:"+ appointment.getSubject() + "\n"
+ "ORGANIZER:MAILTO:" + appointment.getFrom() + "\n"
+ String.format("ATTENDEE;CN=%s;RSVP=TRUE:mailto:%s",
appointment.getTo().stream().findFirst().orElse(null),
appointment.getTo().stream().findFirst().orElse(null))+ "\n"
+ "X-MICROSOFT-CDO-BUSYSTATUS:FREE" + "\n"
+ "BEGIN:VALARM\n"
+ "ACTION:DISPLAY\n"
+ "DESCRIPTION:Reminder\n"
+ "TRIGGER:-P1D\n"
+ "END:VALARM\n"
+ "END:VEVENT\n"
+"END:VCALENDAR");
return buffer.toString();
}
private String createRecurring(Appointment appointment) {
String res = "";
if (appointment.getRecurringFrequency() != null && appointment.getRecurringFrequency().intValue() != 0) {
String frequency = getFrequencyString(appointment.getRecurringFrequency().intValue());
if (appointment.getRecurringEndDate() == null) {
res = "RRULE:FREQ=" + frequency + "\n";
}
else {
String date = extracted(FORMATED_DATE_TIME, 0, appointment.getRecurringEndDate());
res = "RRULE:FREQ=" + frequency + ";UNTIL=" + date + "\n";
}
}
return res;
}
private String extractDstartDend(Appointment appointment) {
StringBuilder res = new StringBuilder();
if (appointment.isIsAllDayEvent()) {
res.append("DTSTART:" + extracted(FORMATED_DATE, 0, appointment.getStartDate()) + "\n");
res.append("DTEND:" + extracted(FORMATED_DATE, 1, appointment.getStartDate()) + "\n");
}
else {
res.append("DTSTART:" + extracted(FORMATED_DATE_TIME, 0, appointment.getStartDate()) + "\n");
res.append("DTEND:" + extracted(FORMATED_DATE_TIME, 0, appointment.getEndDate()) + "\n");
}
return res.toString();
}
Upvotes: 2