[rt-users] FW: scrip and template to email calendar invite

Brent Wiese bwiese at ElementPS.com
Fri Mar 16 14:38:05 EDT 2012


This is a somewhat old thread, but since I got it all working, its baked a while now, and I see a ton of "how do I send outlook invites" with no workable responses, I wanted to share since people here have helped me immensely. It's time to give back!

I'm on RT 4.0.4, but I think it'll work on older versions since the code I changed has been around a while.

A little history:

>> What I need to do is set the Content-Type as: text/calendar; 
>> charset="utf-8"; method=REQUEST

>> Anyone more entrenched in the code able to point me in the right 
>> direction? It'd be great if there was some way to just pass the value 
>> after Content-Type: in the template to the email...

Thomas Sibley wrote back:
> The part that forces text/plain is line 205 in RT::Action::SendEmail (and calls into
> RT::I18N::IsTextualContentType).  The restriction to m{^(?:text/(?:plain|html)|message/rfc822)\b}i
> dates from 2007, and I suspect it should be rewritten to allow arbitrary content-types.

This was the ticket (ha, pun). I copied /opt/rt4/lib/RT/I18N.pm and its I18N supporting folder (didn't work if I didn't copy the folder/contents too) to /opt/rt4/local/lib/RT.

I changed this routine around line 196 in I18N.pm:
sub IsTextualContentType {
    my $type = shift;
    ($type =~ m{^(?:text/(?:plain|html|calendar)|message/rfc822)\b}i) ? 1 : 0;
}

Basically, just adding the "calendar" check to the regex.

Since everyone's scrip usage will be different, I'm not putting mine in here. I'm just checking on a queue change to see if this field has value (it's not required) or if this CF has changed (so it can send an update) once in the queue. Pretty basic scrip.

After the code change, I was able to build a template that would send an invite. The invite is sent with the meeting time pulled from a date-time custom field (CF #19 in my RT). I've fixed a lot of the fields in our case because these are really just placeholders for us (ie: they're set to 30 min lengths because I don't care about having to adjust the lengths and a 15 min prior notification time). You could easily modify those using other custom fields in your setup.

I've also stripped down the vCal lines to keep this simple... things like timezones, required/optional users, etc are all removed. If you put in the "required" lines, people's responses will send back vCal garbage to the organizer if it's not an outlook user (RT in my case) since outlook defaults to "Send response".

I learned almost all of the vCal stuff by sending myself some invites to an account I don't use outlook with and saving the email, opening it in a text editor, and running it through an online base64 decoder. I'm NOT attempting to do multi-part messages like Outlook sends. I didn't need to.

I've seen some people fix the UID field. I decided to use the ticket number since it's unique and this way, meetings will "update" even if the subject of the email/ticket changes.

If the below doesn't give you the accept/tentative/decline buttons, then there is a stray LF somewhere. This was the hardest part during my testing - it required remembering to use ctrl-enter instead of just the enter key when typing things out. If there was a stray LF somewhere, it would show as an attached .ics file or nothing at all.

Template:

Name: Send Calendar Invite
Desc: Sends outlook calendar invite
Type: perl
Content:

Content-Type: text/calendar; charset="utf-8"; method=REQUEST 

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:Microsoft Exchange Server 2007
VERSION:2.0
BEGIN:VEVENT
ORGANIZER;CN=RT:MAILTO:myRTemail at domain.com
DESCRIPTION;LANGUAGE=en-US:See Ticket {RT->Config->Get('WebURL')}Ticket/Display.html?id={$Ticket->id} 
 \n\nDescription of the action to perform:\n{$Ticket->FirstCustomFieldValue(11);} 
SUMMARY;LANGUAGE=en-US:subject
DTSTART:{ my $duedate = RT::Date->new($RT::SystemUser);
 $duedate->Set(Format=>'ISO', Value =>$Ticket->FirstCustomFieldValue(19));
 $duedate = $duedate->AsString(Format=>'iCal');
 $duedate;
}
DTEND:{
 my $newdate = RT::Date->new($RT::SystemUser);
 $newdate->Set(Format=>'ISO', Value => $Ticket->FirstCustomFieldValue(19) );
 $newdate->AddSeconds(+1800);
 $newdate = $newdate->AsString(Format=>'iCal');
 $newdate;
 }
UID:{$Ticket->id}
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:{ my $now = RT::Date->new($RT::SystemUser);
 $now->SetToNow();
 $now = $now->AsString(Format=>'iCal');
 $now;
}
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION;LANGUAGE=en-US:EPS
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:REMINDER
TRIGGER;RELATED=START:-PT15M
END:VALARM
END:VEVENT
END:VCALENDAR

When this comes to an Outlook or iphone-via-exchange user, it works great. Some of our droid users have "always send reply" turned on so it inserts all the vCal text into the ticket. Once identified, we have them turn that off. Another option would be to set the meeting organizer as one of your Outlook users (ie: a project manager).

Would be awesome if a forthcoming version of RT included that "calendar" content-type check.

Cheers,
Brent



More information about the rt-users mailing list