11

I'm trying to send an iCal to an outlook, using Java Mail Library, I've read already the Question, and I already have some sample code

public class SendMeetingRequest {

String host = "" ;
String port = "" ;
String sender = "" ;

public static SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyyMMdd'T'HHmm'00'" ) ;
public static SimpleDateFormat dateParser = new SimpleDateFormat( "dd-MM-yyyy HH:mm" ) ;

public static void main(String[] args) throws Exception {
    SendMeetingRequest sender = new SendMeetingRequest() ;

    sender.sendInvitation( “LogicaCMG Inschrijf Site”
                         , new String[] { “robert<dot>willems<dot>of<dot>brilman<at>logicacmg<dot>com”
                                        }
                         , “Outlook Meeting Request Using JavaMail”
                         , dateParser.parse( “28-08-2006 18:00″ )
                         , dateParser.parse( “28-08-2006 21:00″ )
                         , “LIS-42″
                         , “Bar op scheveningen”
                         , “<font color=\”Red\”>Aanwezigheid verplicht!</font><br>We gaan lekker een biertje drinken met z’n allen.”
                         ) ;
}


void sendInvitation( String organizer
                   , String[] to
                   , String subject
                   , Date start
                   , Date end
                   , String invitationId
                   , String location
                   , String description
                   ) throws Exception {

    try {
        Properties prop = new Properties();
        prop.put(”mail.smtp.port”, port );
        prop.put(”mail.smtp.host”, host );

        Session session = Session.getDefaultInstance(prop);
        session.setDebug(true);

        // Define message
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(sender));

        // Set TO
        if( to != null && ( to.length > 0 ) ) {
            InternetAddress[] address = new InternetAddress[ to.length ] ;

            for( int i = 0; i < to.length; i++ ) {
                address[ i ] = new InternetAddress( to[ i ] ) ;
            }

            message.setRecipients( Message.RecipientType.TO, address ) ;
        }

        // Set subject
        message.setSubject(subject);

        // Create iCalendar message
        StringBuffer messageText = new StringBuffer();
        messageText.append("BEGIN:VCALENDAR\n" +
                           "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n" +
                           "VERSION:2.0\n" +
                           "METHOD:REQUEST\n" +
                               "BEGIN:VEVENT\n" +
                               "ORGANIZER:MAILTO:" ) ;
        messageText.append( organizer ) ;
        messageText.append( "\n" +
                            "DTSTART:");
        messageText.append( dateFormat.format( start ) ) ;
        messageText.append( "\n" +
                            "DTEND:" ) ;
        messageText.append( dateFormat.format( end ) ) ;
        messageText.append( "\n" +
                            "LOCATION:" ) ;
        messageText.append( location ) ;
        messageText.append( "\n" +
                             "UID:" ) ;
        messageText.append( invitationId ) ;
        messageText.append( "\n" +
                            "DTSTAMP:" ) ;
        messageText.append( dateFormat.format( new java.util.Date() ) ) ;
        messageText.append( "\n" +
                            "DESCRIPTION;ALTREP=\"CID:<eventDescriptionHTML>\”" ) ;
        messageText.append( “\n” +
                                    ”BEGIN:VALARM\n” +
                                    ”TRIGGER:-PT15M\n” +
                                    ”ACTION:DISPLAY\n” +
                                    ”DESCRIPTION:Reminder\n” +
                                    ”END:VALARM\n” +
                               ”END:VEVENT\n” +
                           ”END:VCALENDAR”
                           ) ;

        Multipart mp = new MimeMultipart();

        MimeBodyPart meetingPart = new MimeBodyPart() ;
        meetingPart.setDataHandler( new DataHandler( new StringDataSource( messageText.toString(), “text/calendar”, “meetingRequest” ) ) ) ;
        mp.addBodyPart( meetingPart ) ;

        MimeBodyPart descriptionPart = new MimeBodyPart() ;
        descriptionPart.setDataHandler( new DataHandler( new StringDataSource( description, “text/html”, “eventDescription” ) ) ) ;
        descriptionPart.setContentID( “<eventDescriptionHTML>” ) ;
        mp.addBodyPart( descriptionPart ) ;

        message.setContent( mp ) ;

        // send message
        Transport.send(message);

    } catch (MessagingException me) {
        me.printStackTrace();

    } catch (Exception ex) {
        ex.printStackTrace();

    }
}

private static class StringDataSource implements DataSource {
    private String contents ;
    private String mimetype ;
    private String name ;


    public StringDataSource( String contents
                           , String mimetype
                           , String name
                           ) {
        this.contents = contents ;
        this.mimetype = mimetype ;
        this.name = name ;
    }

    public String getContentType() {
        return( mimetype ) ;
    }

    public String getName() {
        return( name ) ;
    }

    public InputStream getInputStream() {
        return( new StringBufferInputStream( contents ) ) ;
    }

    public OutputStream getOutputStream() {
        throw new IllegalAccessError( “This datasource cannot be written to” ) ;
    }
} }

But its being sent as an attachment to the outlook 2007 and outlook 2003, and even If I click the attachment to view and accept, I don't receive the Answer, which is the purpose of the application to have a similar functionality like outlook.

Is there any procedure I need to know of, or is it the Invitation ID that makes the thing rough?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Amr Gawish
  • 2,015
  • 1
  • 17
  • 29

5 Answers5

26

So I solved the problem, and here is what I found:

1 - You have to update to Java Mail API 1.4.2 to make everything works fine

2 - Write the text/calendar part of your message like the following:

package com.xx.xx;

import java.util.Properties;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;

public class Email {

    public Email() {
    }

    /*
     * @param args
     */
    public static void main(String[] args) {
        try {
            Email email = new Email();
            email.send();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void send() throws Exception {

        try {
            String from = "xx@xx.com";
            String to = "xx@xx.com";
            Properties prop = new Properties();
            prop.put("mail.smtp.host", "mailhost");

            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");

            message.setFrom(new InternetAddress(from));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setSubject("Outlook Meeting Request Using JavaMail");

            StringBuffer sb = new StringBuffer();

            StringBuffer buffer = sb.append("BEGIN:VCALENDAR\n" +
                    "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n" +
                    "VERSION:2.0\n" +
                    "METHOD:REQUEST\n" +
                    "BEGIN:VEVENT\n" +
                    "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:xx@xx.com\n" +
                    "ORGANIZER:MAILTO:xx@xx.com\n" +
                    "DTSTART:20051208T053000Z\n" +
                    "DTEND:20051208T060000Z\n" +
                    "LOCATION:Conference room\n" +
                    "TRANSP:OPAQUE\n" +
                    "SEQUENCE:0\n" +
                    "UID:040000008200E00074C5B7101A82E00800000000002FF466CE3AC5010000000000000000100\n" +
                    " 000004377FE5C37984842BF9440448399EB02\n" +
                    "DTSTAMP:20051206T120102Z\n" +
                    "CATEGORIES:Meeting\n" +
                    "DESCRIPTION:This the description of the meeting.\n\n" +
                    "SUMMARY:Test meeting request\n" +
                    "PRIORITY:5\n" +
                    "CLASS:PUBLIC\n" +
                    "BEGIN:VALARM\n" +
                    "TRIGGER:PT1440M\n" +
                    "ACTION:DISPLAY\n" +
                    "DESCRIPTION:Reminder\n" +
                    "END:VALARM\n" +
                    "END:VEVENT\n" +
                    "END:VCALENDAR");

            // 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(buffer.toString(), "text/calendar")));// very important

            // Create a Multipart
            Multipart multipart = new MimeMultipart();

            // Add part one
            multipart.addBodyPart(messageBodyPart);

            // Put parts in message
            message.setContent(multipart);

            // send message
            Transport.send(message);
        } catch (MessagingException me) {
            me.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

3 - Replace your variable, and you are good to go!

user1516873
  • 5,060
  • 2
  • 37
  • 56
Amr Gawish
  • 2,015
  • 1
  • 17
  • 29
  • Hi Amr, I'm working with the same sort of project for my academic, i need to raise the alerts and remainders of a meeting, i'm using java to develop this all my design is upto mark but the icall api to an outlook is difficult to do so could you please help me out in doing this !. – 09Q71AO534 Sep 05 '13 at 07:13
  • Hi @user2561626 If you used the code in here you should be able to raise the alert and reminder is just function for Outlook itself, so there are no control over it. – Amr Gawish Sep 05 '13 at 11:46
  • i have the ical4j downloaded , should i change any methods in it, for making this code in here work, for raising the alerts and remainders. – 09Q71AO534 Sep 05 '13 at 11:53
  • i have downloaded the file from [this link](http://sourceforge.net/projects/ical4j/files/iCal4j/). i'm new in using ical api,please help me out. – 09Q71AO534 Sep 05 '13 at 11:59
  • Check the examples in here: http://wiki.modularity.net.au/ical4j/index.php?title=Examples – Amr Gawish Sep 05 '13 at 13:16
  • Thank u for this support.if any doubt i will text u back :-) – 09Q71AO534 Sep 05 '13 at 13:18
  • Hi,Amr i'm able to send the meeting invitation,but i'm unable to code for the acceptance they click on! (whether they accept/reject/tentative). How should i solve this! – 09Q71AO534 Sep 13 '13 at 12:50
  • The iCal4J doesn't support this. – Amr Gawish Sep 13 '13 at 15:36
  • Then is there any other way to do that. Amr – 09Q71AO534 Sep 13 '13 at 15:40
  • The confirmation comes to the Sender's mail, you have to use the Mail API to read the mails that the sender's received in order to get the confirmations – Amr Gawish Sep 13 '13 at 16:03
  • @AmrGawish Thanks a lot for your code, it saved me lot of time. God bless you. – bprasanna May 27 '15 at 10:38
  • @09Q71AO534 It is up to the IMIP client to choose if to offer or not the ability to "import" that event or to show "RSVP" action for it. But, the iTIP/iMIP protocol does not cover the scenario of "inviting the organizer" via email. Meaning, the action buttons wouldn't be shown on most IMIP clients, when the organizer receives the meeting by email. See http://stackoverflow.com/questions/35604423/when-creating-an-ical-event-on-behalf-of-an-organizer-and-email-it-to-him-no-a/35621380#35621380 – RonyK Feb 25 '16 at 10:02
6

You can use ical4j library in addition of javamail to build the message body (instead of using a StringBuffer).

Example:

Calendar calendar = new Calendar();
PropertyList calendarProperties = calendar.getProperties();
calendarProperties.add(Version.VERSION_2_0);
calendarProperties.add(Method.REQUEST);
// other properties ...

VEvent vEvent = new VEvent(/*startDate, endDate*/);
PropertyList vEventProperties = vEvent.getProperties();
vEventProperties.add(Priority.MEDIUM);
vEventProperties.add(Clazz.PUBLIC);
// other properties ...

calendar.getComponents().add(vEvent);

messageBodyPart.setDataHandler(new DataHandler(new ByteArrayDataSource(calendar.toString(), "text/calendar")));
herau
  • 1,466
  • 2
  • 18
  • 36
1

There's no sign that you're ever setting the from address to an actual address, so there's nowhere for the reply to come.

That may not be the problem in your production code, but it looks like a problem here...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

I'd tried with Amr answer but I got an error in Session session = Session.getDefaultInstance(prop, null),

Well I fixed and here is the code I used and it worked perfectly. I hope it helps
Remember you need to add javax.mail library to your project

import java.util.Properties;
import javax.activation.DataHandler;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;

public class Email {

 public Email() {
 }

 public static void main(String[] args) {
     try {
         Email email = new Email();
         email.send();
     } catch (Exception e) {
         e.printStackTrace();
     }
 }

 public void send() throws Exception {

    try {
        String from = "FromExample@gmail.com";
        String to = "ToExample@gmail.do";
        Properties prop = new Properties();

        prop.put("mail.smtp.auth", "true");
        prop.put("mail.smtp.starttls.enable", "true");
        prop.put("mail.smtp.host", "smtp.gmail.com");
        prop.put("mail.smtp.port", "587");

        final String username = "FromExample@gmail.com";
        final String password = "123456789";

        Session session = Session.getInstance(prop,
                  new javax.mail.Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password);
                    }
                  });

        // Define message
        MimeMessage message = new MimeMessage(session);
        message.addHeaderLine("method=REQUEST");
        message.addHeaderLine("charset=UTF-8");
        message.addHeaderLine("component=VEVENT");

        message.setFrom(new InternetAddress(from));
        message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
        message.setSubject("Outlook Meeting Request Using JavaMail");

        StringBuffer sb = new StringBuffer();

        StringBuffer buffer = sb.append("BEGIN:VCALENDAR\n" +
                "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n" +
                "VERSION:2.0\n" +
                "METHOD:REQUEST\n" +
                "BEGIN:VEVENT\n" +
                "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:xxx@xx.com\n" +
                "ORGANIZER:MAILTO:xx@xx.com\n" +
                "DTSTART:20180922T053000Z\n" +
                "DTEND:20180927T060000Z\n" +
                "LOCATION:Conference room\n" +
                "TRANSP:OPAQUE\n" +
                "SEQUENCE:0\n" +
                "UID:040000008200E00074C5B7101A82E00800000000002FF466CE3AC5010000000000000000100\n" +
                " 000004377FE5C37984842BF9440448399EB02\n" +
                "DTSTAMP:20180922T120102Z\n" +
                "CATEGORIES:Meeting\n" +
                "DESCRIPTION:This the description of the meeting.\n\n" +
                "SUMMARY:Test meeting request\n" +
                "PRIORITY:5\n" +
                "CLASS:PUBLIC\n" +
                "BEGIN:VALARM\n" +
                "TRIGGER:PT1440M\n" +
                "ACTION:DISPLAY\n" +
                "DESCRIPTION:Reminder\n" +
                "END:VALARM\n" +
                "END:VEVENT\n" +
                "END:VCALENDAR");

        // 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(buffer.toString(), "text/calendar")));// very important

        // Create a Multipart
        Multipart multipart = new MimeMultipart();

        // Add part one
        multipart.addBodyPart(messageBodyPart);

        // Put parts in message
        message.setContent(multipart);

        // send message


        Transport.send(message);

        System.out.println("Success");

    } catch (MessagingException me) {
        me.printStackTrace();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
 }
}
Juan Sanchez
  • 543
  • 7
  • 14
0

Here,

1 - Download jar from here (JavaMail API » 1.6.2).

2 - Copy and Paste the following code (Change variable values)

import java.util.Properties;
import javax.activation.DataHandler;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;

public class Index {

public static void main(String[] args) {

     try {
            final String username = "sender@mail.com";
            final String password = "xxxxx";
            
            String from = "sender@mail.com";
            String to = "attendee@mail.com";
            String subject = "Meeting Subject";
            String startDate = "20201208"; // Date Formate: YYYYMMDD
            String endDate = "20201208"; // Date Formate: YYYYMMDD
            String startTime = "0400"; // Time Formate: HHMM
            String endTime = "0600"; // Time Formate: HHMM
            String emailBody = "Hi Team, This is meeting description. Thanks"; 
            
            Properties prop = new Properties();
            prop.put("mail.smtp.auth", "true");
            prop.put("mail.smtp.starttls.enable", "true");
            prop.put("mail.smtp.host", "smtp.gmail.com");
            prop.put("mail.smtp.port", "25");

            Session session = Session.getDefaultInstance(prop,  new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
              });
            
            MimeMessage message = new MimeMessage(session);
            message.addHeaderLine("method=REQUEST");
            message.addHeaderLine("charset=UTF-8");
            message.addHeaderLine("component=VEVENT");

            message.setFrom(new InternetAddress(from, "New Outlook Event"));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setSubject(subject);

            StringBuffer sb = new StringBuffer();

            StringBuffer buffer = sb.append("BEGIN:VCALENDAR\n" +
                    "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n" +
                    "VERSION:2.0\n" +
                    "METHOD:REQUEST\n" +
                    "BEGIN:VEVENT\n" +
                    "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:"+ to +"\n" +
                    "DTSTART:"+ startDate +"T"+ startTime +"00Z\n" +
                    "DTEND:"+ endDate +"T"+ endTime +"00Z\n" +
                    "LOCATION:Conference room\n" +
                    "TRANSP:OPAQUE\n" +
                    "SEQUENCE:0\n" +
                    "UID:040000008200E00074C5B7101A82E00800000000002FF466CE3AC5010000000000000000100\n" +
                    " 000004377FE5C37984842BF9440448399EB02\n" +
                    "CATEGORIES:Meeting\n" +
                    "DESCRIPTION:"+ emailBody +"\n\n" +
                    "SUMMARY:Test meeting request\n" +
                    "PRIORITY:5\n" +
                    "CLASS:PUBLIC\n" +
                    "BEGIN:VALARM\n" +
                    "TRIGGER:PT1440M\n" +
                    "ACTION:DISPLAY\n" +
                    "DESCRIPTION:Reminder\n" +
                    "END:VALARM\n" +
                    "END:VEVENT\n" +
                    "END:VCALENDAR");

            // 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(buffer.toString(), "text/calendar")));// very important

            // Create a Multipart
            Multipart multipart = new MimeMultipart();

            // Add part one
            multipart.addBodyPart(messageBodyPart);

            // Put parts in message
            message.setContent(multipart);

            // send message
            Transport.send(message);
            
            System.out.println("Email sent!");
        } catch (MessagingException me) {
            me.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
}
}

3 - That's all, hit RUN......

Jay
  • 308
  • 2
  • 10