So it was a little more difficult to do this (Gel has problems with nested static classes!). OK, here is how it works.
Using standard java mail, we create a mime multipart message. The first part of the message is the email text you wish to set to the attendees. The second part is the vcalendar file holding the meeting information.
I have the following “After Work Status Meeting “ meeting schedule for 4PM Pacific Standard Time. You would need to replace elements for each meeting sent out and deal with timezone issues but this will give you the idea on how to format a vcs file.
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 14.0 MIMEDIR//EN
VERSION:2.0
METHOD:PUBLISH
X-MS-OLK-FORCEINSPECTOROPEN:TRUE
BEGIN:VTIMEZONE
TZID:Pacific Standard Time
BEGIN:STANDARD
DTSTART:16011104T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010311T020000
RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
CLASS:PUBLIC
CREATED:20140926T192104Z
DTEND;TZID="Pacific Standard Time":20140926T160000
DTSTAMP:20140926T192104Z
DTSTART;TZID="Pacific Standard Time":20140926T150000
LAST-MODIFIED:20140926T192104Z
LOCATION:Friendly Watering Hole
PRIORITY:5
SEQUENCE:0
SUMMARY;LANGUAGE=en-us:After Work Status Meeting
TRANSP:OPAQUE
UID:040000008200E00074C5B7101A82E00800000000609CB31B84D9CF01000000000000000
01000000017C3704930350F43B81ED6789C58B791
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MS-OLK-AUTOFILLLOCATION:FALSE
X-MS-OLK-CONFTYPE:0
BEGIN:VALARM
Now for a working script. For getting the running clarity email properties, see this post: https://communities.ca.com/thread/101857694 (Great post and got me passed the nested static class issue that you also ran into).
Our OnDemand development environment doesn’t have email, so I just pointed the script to an external SMTP server (SSL and Authentication requirements). This script also has mail debugging turn on so it tosses a lot of mail connection information to the console.
<gel:script
xmlns:core="jelly:core"
xmlns:util="jelly:util"
xmlns:x="jelly:xml"
xmlns:gel="jelly:com.niku.union.gel.GELTagLibrary"
xmlns:soap="jelly:com.niku.union.gel.SOAPTagLibrary"
>
<!-- Set up our email server variables You should abe able to get them off the properties file -->
<gel:parameter var='mailHost' default='mail.server.com'/>
<gel:parameter var='mailPort' default='465'/>
<gel:parameter var='mailUser' default='user'/>
<gel:parameter var='mailPasswod' default='password/>
<gel:parameter var='mailFromAddress' default='user@server.com'/>
<gel:parameter var='mailToAddress' default='user@server.com'/>
<!-- Place our mail settings in our properties object -->
<core:new className='java.util.Properties' var='propertiesClass'/>
<core:set value='${propertiesClass.put("mail.transport.protocol", "smtp")}' var="void" />
<core:set value='${propertiesClass.put("mail.smtp.socketFactory.port","465")}' var="void" />
<core:set value='${propertiesClass.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory")}' var="void" />
<core:set value='${propertiesClass.put("mail.smtp.host", mailHost)}' var="void" />
<core:set value='${propertiesClass.put("mail.smtp.port", mailPort)}' var="void" />
<core:set value='${propertiesClass.put("mail.smtp.auth", "true")}' var="void" />
<core:set value='${propertiesClass.put("mail.user", mailUser)}' var="void" />
<core:set value='${propertiesClass.put("mail.smtp.debug", "true")}' var='void' />
<!-- Create session Object -->
<core:invokeStatic var='sessionClass' className='javax.mail.Session' method='getInstance'>
<core:arg type='java.util.Properties' value='${propertiesClass}'/>
</core:invokeStatic>
<!-- Set up our PasswordAuthentication to use with our mail session -->
<core:new var='passwordAuthentication' className='javax.mail.PasswordAuthentication'>
<core:arg type='java.lang.String' value='${mailUser}'/>
<core:arg type='java.lang.String' value='${mailPasswod}'/>
</core:new>
<core:new var='uRLName' className='javax.mail.URLName'>
<core:arg type='java.lang.String' value='smtp'/>
<core:arg type='java.lang.String' value='${mailHost}'/>
<core:arg type='int' value='-1'/>
<core:arg type='java.lang.String' value=''/>
<core:arg type='java.lang.String' value='${mailUser}'/>
<core:arg type='java.lang.String' value='${mailPasswod}'/>
</core:new>
<core:invoke method='setPasswordAuthentication' on='${sessionClass}'>
<core:arg type='javax.mail.URLName' value='${uRLName}'/>
<core:arg type='javax.mail.PasswordAuthentication' value='${passwordAuthentication}'/>
</core:invoke>
<core:set value='${sessionClass.setDebug(true)}' var='void' />
<!-- Create our MimeMessage Object -->
<core:new var='mimeMessage' className='javax.mail.internet.MimeMessage'>
<core:arg type='javax.mail.Session' value='${sessionClass}'/>
</core:new>
<!-- Set our headers for this message to VENENT -->
<core:expr value='${mimeMessage.addHeaderLine("method=REQUEST")}' />
<core:expr value='${mimeMessage.addHeaderLine("charset=UTF-8")}' />
<core:expr value='${mimeMessage.addHeaderLine("component=VEVENT")}' />
<!-- Build a From Address -->
<core:new var='fromAddress' className='javax.mail.internet.InternetAddress'>
<core:arg type='java.lang.String' value='${mailFromAddress}'/>
</core:new>
<core:new var='toAddress' className='javax.mail.internet.InternetAddress'>
<core:arg type='java.lang.String' value='${mailToAddress}'/>
</core:new>
<!-- Set our message From / To / Subject values -->
<core:invokeStatic className='java.lang.Class' method='forName' var='recipientType'>
<core:arg type='java.lang.String' value='javax.mail.Message$RecipientType' />
</core:invokeStatic>
<core:set value='${recipientType.getField("TO")}' var='recipientTypeTO' />
<core:set value='${recipientTypeTO.TO}' var='recipientTypeTO' />
<core:set value='${recipientType.getField("CC")}' var='recipientTypeCC' />
<core:set value='${recipientTypeCC.CC}' var='recipientTypeCC' />
<core:set value='${recipientType.getField("BCC")}' var='recipientTypeBCC' />
<core:set value='${recipientTypeBCC.BCC}' var='recipientTypeBCC' />
<core:set value='${mimeMessage.setFrom(fromAddress)}' var='void' />
<core:set value='${mimeMessage.setRecipient(recipientTypeTO, toAddress)}' var='void' />
<core:expr value='${mimeMessage.setSubject("Outlook Meeting Request Using Gel")}' />;
<!-- Build our ugly iCalendar in a string buffer -->
<core:new var='stringBuffer' className='java.lang.StringBuffer' />
<core:set var='newLine' value='${context.getVariable("line.separator")}' />
<core:mute>
<core:expr value='${stringBuffer.append("BEGIN:VCALENDAR"+newLine)}' />
<core:expr value='${stringBuffer.append("PRODID:-//Microsoft Corporation//Outlook 14.0 MIMEDIR//EN"+newLine)}' />
<core:expr value='${stringBuffer.append("VERSION:2.0"+newLine)}' />
<core:expr value='${stringBuffer.append("METHOD:PUBLISH"+newLine)}' />
<core:expr value='${stringBuffer.append("X-MS-OLK-FORCEINSPECTOROPEN:TRUE"+newLine)}' />
<core:expr value='${stringBuffer.append("BEGIN:VTIMEZONE"+newLine)}' />
<core:expr value='${stringBuffer.append("TZID:Pacific Standard Time"+newLine)}' />
<core:expr value='${stringBuffer.append("BEGIN:STANDARD"+newLine)}' />
<core:expr value='${stringBuffer.append("DTSTART:16011104T020000"+newLine)}' />
<core:expr value='${stringBuffer.append("RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11"+newLine)}' />
<core:expr value='${stringBuffer.append("TZOFFSETFROM:-0700"+newLine)}' />
<core:expr value='${stringBuffer.append("TZOFFSETTO:-0800"+newLine)}' />
<core:expr value='${stringBuffer.append("END:STANDARD"+newLine)}' />
<core:expr value='${stringBuffer.append("BEGIN:DAYLIGHT"+newLine)}' />
<core:expr value='${stringBuffer.append("DTSTART:16010311T020000"+newLine)}' />
<core:expr value='${stringBuffer.append("RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3"+newLine)}' />
<core:expr value='${stringBuffer.append("TZOFFSETFROM:-0800"+newLine)}' />
<core:expr value='${stringBuffer.append("TZOFFSETTO:-0700"+newLine)}' />
<core:expr value='${stringBuffer.append("END:DAYLIGHT"+newLine)}' />
<core:expr value='${stringBuffer.append("END:VTIMEZONE"+newLine)}' />
<core:expr value='${stringBuffer.append("BEGIN:VEVENT"+newLine)}' />
<core:expr value='${stringBuffer.append("CLASS:PUBLIC"+newLine)}' />
<core:expr value='${stringBuffer.append("CREATED:20140926T192104Z"+newLine)}' />
<core:expr value='${stringBuffer.append("DTEND;TZID=Pacific Standard Time:20140926T160000"+newLine)}' />
<core:expr value='${stringBuffer.append("DTSTAMP:20140926T192104Z"+newLine)}' />
<core:expr value='${stringBuffer.append("DTSTART;TZID=Pacific Standard Time:20140926T150000"+newLine)}' />
<core:expr value='${stringBuffer.append("LAST-MODIFIED:20140926T192104Z"+newLine)}' />
<core:expr value='${stringBuffer.append("LOCATION:Friendly Watering Hole"+newLine)}' />
<core:expr value='${stringBuffer.append("PRIORITY:5"+newLine)}' />
<core:expr value='${stringBuffer.append("SEQUENCE:0"+newLine)}' />
<core:expr value='${stringBuffer.append("SUMMARY;LANGUAGE=en-us:After Work Status Meeting"+newLine)}' />
<core:expr value='${stringBuffer.append("TRANSP:OPAQUE"+newLine)}' />
<core:expr value='${stringBuffer.append("UID:040000008200E00074C5B7101A82E00800000000609CB31B84D9CF01000000000000000"+newLine)}' />
<core:expr value='${stringBuffer.append(" 01000000017C3704930350F43B81ED6789C58B791"+newLine)}' />
<core:expr value='${stringBuffer.append("X-MICROSOFT-CDO-BUSYSTATUS:BUSY"+newLine)}' />
<core:expr value='${stringBuffer.append("X-MICROSOFT-CDO-IMPORTANCE:1"+newLine)}' />
<core:expr value='${stringBuffer.append("X-MICROSOFT-DISALLOW-COUNTER:FALSE"+newLine)}' />
<core:expr value='${stringBuffer.append("X-MS-OLK-AUTOFILLLOCATION:FALSE"+newLine)}' />
<core:expr value='${stringBuffer.append("X-MS-OLK-CONFTYPE:0"+newLine)}' />
<core:expr value='${stringBuffer.append("BEGIN:VALARM"+newLine)}' />
<core:expr value='${stringBuffer.append("TRIGGER:-PT15M"+newLine)}' />
<core:expr value='${stringBuffer.append("ACTION:DISPLAY"+newLine)}' />
<core:expr value='${stringBuffer.append("DESCRIPTION:Reminder"+newLine)}' />
<core:expr value='${stringBuffer.append("END:VALARM"+newLine)}' />
<core:expr value='${stringBuffer.append("END:VEVENT"+newLine)}' />
<core:expr value='${stringBuffer.append("END:VCALENDAR"+newLine)}' />
</core:mute>
<gel:log>${stringBuffer.toString()}</gel:log>
<!-- Build up our MimeMultipart message -->
<core:new var='mimeMultipart' className='javax.mail.internet.MimeMultipart' />
<core:set value='${mimeMessage.setContent(mimeMultipart)}' var='void' />
<!-- Message about the meeting -->
<core:new var='messageBodyPartText' className='javax.mail.internet.MimeBodyPart' />
<core:set value='${messageBodyPartText.setText("Please see attached meeting request")}' var='void' />
<core:set value='${mimeMultipart.addBodyPart(messageBodyPartText)}' var='void' />
<!-- Attached VCalendar -->
<core:new var='messageBodyPartVcs' className='javax.mail.internet.MimeBodyPart' />
<core:set value='${messageBodyPartVcs.setFileName("MeetingRequest.vcs")}' var='void' />
<core:set value='${messageBodyPartVcs.setContent(stringBuffer.toString(), "text/plain")}' var='void' />
<core:set value='${mimeMultipart.addBodyPart(messageBodyPartVcs)}' var='void' />
<!-- Send our invite -->
<core:set var='transport' value='${sessionClass.getTransport(uRLName)}' />
<core:set var='connect' value='${transport.connect(mailHost, mailPort, mailUser, mailPasswod)}' />
<gel:log>Connected = ${transport.isConnected()}</gel:log>
<core:set var='void' value='${transport.send(mimeMessage)}' />
</gel:script>
The script runs and we get our email.
We open it an see our message along with the vcs file attachment:
We double click on our MeetingRequest.vcs and see the meeting details:
We save & close the meeting request and check our calendar:
V/r,
Gene