FW: scrip and template to email calendar invite

My assumption is I would need to build a new template. What I
can’t figure out is the code
that goes in the template so the text I’m adding isn’t just parsed
as the message content
itself.

You may want to review the docs/customizing/templates.pod included with
RT, which also talks about how to set a custom header type.

You won’t be able to build an attachment from your Template, so
hopefully an inline solution works.

-kevin

It looks like the only custom Content-Type is text/html. I can see where it looks for that in Template.pm.

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

I put an elsif in Template.pm to see if I could get it to pass that header on like text/html but it’s not working.

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…

In my case, I actually don’t need any readable message content outside of that Content-Type…

Thanks,
Brent

It looks like the only custom Content-Type is text/html. I can see
where it looks for that in Template.pm.

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

I put an elsif in Template.pm to see if I could get it to pass that
header on like text/html but it’s not working.

Yep, that’s the wrong place. The code block you’re looking at in
RT::Template is not forcing a content-type, just defaulting differently
based on what’s in your template.

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…

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.

Arbitrary content-types can be a problem if you’re letting lots of
admins edit templates, but presumably if you’re letting them modify
templates, you already have some degree of trust in them.

Thomas

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@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