Bradford Shelle
Kilo Guru
Hey folks,

 

This is a tutorial on how to set up Calendar Invites to be sent to Outlook via ServiceNow, along with potentially how to capture any responses the invitees send back.

Update Feb 12, 2020: Official ServiceNow documentation for reference: https://docs.servicenow.com/bundle/newyork-servicenow-platform/page/administer/notification/referenc... 

 

 

 

What we can do with this feature
  • Send new calendar invites from ServiceNow to email clients
  • Update existing calendar invites created by ServiceNow
  • Delete existing calendar invites
  • Update ServiceNow when an invite is accepted/tentatived/declined*
  • Update ServiceNow when an invite has notes added to the body*

 

Requirements
  • Instance running at least Calgary, maybe even Berlin
  • Subproduction instance set to email a specific email address is highly recommended
  • Outlook, though other email clients can work*
  • A table that contains two fields that are in the date/time format
  • Lots of patience

 

Knowledge Needed
  • A little knowledge on how iCalendar works
  • Creating notifications
  • Creating email templates
  • Creating business rules OPTIONAL
  • Creating events OPTIONAL
  • Basic Javascript
  • How to Google

Limitations
  • Reoccurring calendar invites are incredibly complicated (might dive into this later)
  • Mail scripting is unavailable when sending calendar invites
  • Can't account for all mail clients or the human element when transforming responses sent back to ServiceNow
  • Different mail servers interact with meetings in slightly different ways (Exchange 07/10/13, O365, Gmail)
  • HTML is possible to use....sort of. We'll touch on this a little

 


Together we'll walk through how this process works and a lot of the nuances that come up along the way. This by no means 100% covers all aspects of how to utilize this function of ServiceNow, but hopefully touches on a bit more than just the scattered Wiki articles and Google search results. I'm positive that there will be some better or more creative solutions out there on how to handle certain sections of this guide, and I hope that the community is positive and willing to share such information!

 

Defining Criteria

 

First we need to identify which table is going to house the information that will be in our meeting invites. The most critical pieces of information that have to be in this table are the start date/time and end date/time. BOTH THESE PIECES OF INFORMATION HAVE TO COME FROM A DATE/TIME FIELD. Everything else, who it gets sent to, the subject, the location, the body, can be fanangled some other way, but when the meeting should start and end have to be fields in a table.

 

Next, we need a way to trigger the system to send out these calendar invites. This can be done one of two ways

  1. Conditions that are built into a notification
  2. Event that triggers a notification, either through a business rule or workflow
This is personal preference, and depends on your own requirements of when calendar invites should be sent.

 

Event Based Notifications

If you choose to use events, I recommend creating three new events in the event registry (System Policy -> Events -> Registry)

  1. One event for new calendar invites
  2. One event for updating existing calendar invites
  3. One event for deleting existing calendar invites
Please consult this Wiki if you are not familiar with creating new events

 

Now that we have built our events, we need to create a trigger to fire them off.
We can either do this with a business rule, or with a workflow. It might be possible to do it based off a client script that calls a script include, but I won't get into that in this article.

For a business rule, we need to set up some simple IF statements to tell the system when to fire the event and what the event will contain for parameters. The previous Wiki article contains several examples on how this works, and I highly recommend taking a look at it.

Example

if (current.operation() == 'insert') {
  gs.eventQueue("change.inserted", current, gs.getUserID(), gs.getUserName());
}

This is even easier with a workflow, as there is an event trigger that you can drag in and tell the system which event to fire and what the parameters should be at any point of the workflow.

 

The Notification Part 1
 
Let's build up a new notification that will handle sending out the calendar invite. You might need more than one to handle inserting, updating, and deleting calendar invites, but we'll start with just one.

NOTE:
While you have a blank notification in front of you, you might need to personalize the form to show the "Type" field. We need to change this field from "EMAIL" to "Meeting Invitation".

  1. Select the table that we defined earlier and has our two date/time fields in it.
  2. We need to set when the notification will fire. If you chose to go the event route, select your event here. If you are using conditions, now is the time to define them.
  3. Set the "Content type" field on the "What it will contain" tab to "Plain text only". That's right, we can't do any mail scripting here. It's very annoying and greatly reduces the flexibility of the notification, but as of Eureka (and probably Fuji), we have to send out a plain text notification to make this work.

 

Please consult this Wiki if you are not familiar with creating notifications

 

That's it for now. Let's save this notification as we will come back to it later for a few more things.

 

The Import Export Maps Table
 
Our next step is to have ServiceNow translate those two date/time fields I keep on mentioning into a format that iCalendar recognizes. The quickest way to get there is to type sys_impex_map.list into your Type Filter Text on the left side, or search for that in the list of tables.

We only need to create one new entry here. Click the new button. For the name of the new record, it has to be icalendar.your_table_name. Typing in something else or misspelling the table name will result in the start and end times for the calendar event to not work correctly.
Select the table in question as well, and make sure that the "Type" field is "icalendar".
You can give the record a description as well if you want, but otherwise we can save the record.

 

Some related lists will appear. We are interested in the "Field Maps" related list.
Click "New", and you will be greeted by a wizard. Select "Mapping to a database field" to continue.
Here we can see that the "Map" and "Table" fields are already filled out. There are only two that we need to fill in.
For "External Name", we now start to get into the iCalendar language.

  • dtstart - this denotes when a calendar invite will start REQUIRED
  • dtend - this denotes when a calendar invite will end REQUIRED
  • description - if you have a multi line description, we'll need to enter this in so that line breaks are handled correctly OPTIONAL
  • alarm_time - if you want to have a flexible time for an alarm to trigger, this is needed for the date/time to translate correctly OPTIONAL
Enter in one of those names into the "External Name" field. Again, dtstart and dtend are required for this to work.
Finally select the field under "Database Field" that houses the information in question. So dtstart would go to the field you have denoted as when the meeting should begin, dtend to the end of the meeting, etc.

 

Click update and we're on our way. Continue the process until you at lease have dtstart and dtend mapped, and if it's relevant, description and/or alarm_time.

More useful information can be found in this wiki article.

 

Notification Template

We now need to create a notification template that will house the iCalendar code which is used by Outlook to create the meeting.
Go to System Policy -> Email -> Templates, and click New.

Name it whatever you'd like, and select the same table that we keep on using.
IMPORTANT NOTE: Prior to Eureka, everything we type will go into the Message box. Eureka and after, it will either go into the Message box, or the Message text box if you've switched to the Rich HTML Editor. DO NOT POST THE ICALENDAR SCRIPT INTO THE Message HTML BOX AS YOU WILL RECEIVE AN INVALID .ICS FILE!!!

These websites contain very detailed breakdowns of all the different faces of how iCalendar works. It's very technical, but thorough and contains many examples.


There are a lot of lines we can add/remove or different lines we can change. We're going to stick with the basics plus a few useful extras in this article though.
We can reference fields from the table here and dot walk by using the ${field_name} notation here. Please remember though that any form of scripting is not allowed. For example, doing a ${URI_REF} will not produce a beautiful html hyperlink to your record, but instead will show a <a href>"https://blah blah blah"record number</a href> instead. Outlook 2013 is smart enough to identify a hyperlink and automatically make it selectable, but something like OWA is not, and will just show the link in plain text.

 

The Templates

Use this for inserting new calendar events or updating existing one.

BEGIN:VCALENDAR
PRODID:-//Service-now.com//Outlook 11.0 MIMEDIR//EN
VERSION:2.0
METHOD:REQUEST
BEGIN:VEVENT
ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:${to}
ORGANIZER:MAILTO:from email address
LOCATION:meeting location
DTSTART:${dtstart}
DTEND:${dtend}
UID:${sys_id}
DTSTAMP:${dtstamp}
DESCRIPTION:meeting body
SUMMARY:subject line
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-DISALLOW-COUNTER:TRUE
X-SNSYSID:${sys_id}
BEGIN:VALARM
TRIGGER:-PT15M
ACTION:DISPLAY
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR

 

Notes

ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO: - Who the invite will go to. Either specify a field here, or use ${to} if this is defined in the notification
ORGANIZER:MAILTO: - Who is listed as the organizer. Recommend inserting the email for your instance if you want to be able to process attendee responses. NOTE: If you want this to be the email address for your ServiceNow instance, we can't use a system property here, so the easiest way is to hardcode it. Just remember that when testing.
LOCATION: - Where the meeting will be held
DTSTART:${dtstart} - Our field from the sys_impex_map table. DO NOT CHANGE
DTEND:${dtend} - Our field from the sys_impex_map table. DO NOT CHANGE
UID:${sys_id} - Unique identifier of the calendar invite. Recommend using the sys_id of the record you are sending this invite from. NOTE: If you want to process responses, I recommend putting 'your_table_name${sys_id}' as it will save us some time later.
DTSTAMP:${dtstamp} - Don't 100% remember what this is for, but let's just leave it be.
DESCRIPTION: - What shows up in the body of the invite. Can omit if defining the body in the notification
SUMMARY: - The subject line. Can omit if defining the subject in the notification
X-MICROSOFT-CDO-BUSYSTATUS:BUSY - Defines if the attendee is busy/free/etc.
X-MICROSOFT-DISALLOW-COUNTER:TRUE - Prevents the attendees from proposing new times.
X-SNSYSID:{$sys_id} - Some other unique identifier. Again just use the sys_id
BEGIN:VALARM - Sets up an alarm if wanted. Can omit the section between here and END:VALARM if no alarm is desired
TRIGGER:-PT15M - How soon before the meeting will the alarm pop up. In this example, it is for 15 minutes
 
NOTE FOR GMAIL USERS: Just recently discovered that in it's current state (as of Oct 24th 2016), gmail does not accept the VALARM parameter. Please delete out anything involving the VALARM if you plan on sending the invites to a gmail client.

 

Use this for canceling old calendar events

BEGIN:VCALENDAR
PRODID:-//Service-now.com//Outlook 11.0 MIMEDIR//EN
VERSION:2.0
METHOD:CANCEL
BEGIN:VEVENT
STATUS:CANCELLED
ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=FALSE:MAILTO: ${to}
DTSTART:${dtstart}
DTEND:${dtend}
UID:${sys_id}
DTSTAMP:${dtstamp}
DESCRIPTION:
END:VEVENT
END:VCALENDAR

 

Notes

METHOD:CANCEL - Note that the method has changed to CANCEL
STATUS:CANCELLED - Note that we have added this new STATUS line

 


The template for inserting or updating a meeting invitation can be the same template if you wish. If you'd like to communicate to the attendees that there has been an update to the calendar invite, then you can do that with either separate templates or with separate notifications. Up to you.
The cancellation code has to live in its own template since it is so different.

 

The Notification Part 2

Now that our template is complete, let's head back to the notification we built earlier so we can add in the template and do some finishing touches.
Open up your notification, and reference the email template that you just built in the "What it will contain" tab. You can use the "Who will receive" section without any issues to define who will be sent the calendar invite without issue.


 

If you'd like different calendar invites to be sent out for a new invite vs an update, make sure to at the least create another notification if not another template as well depending on what you'd like to be different. Also if you'd like to be able to delete invites, you will need another template and notification for that.

 

Save the notification, and now we're ready for testing!

If all goes well, you will receive a shiny new meeting invite in your Outlook with the dates, times, subject, location, etc. that you specified earlier. You can also look at the email logs to check the recipient to see if it was addressed correctly, even if your emails are set to go to a specific email address.
Check down below if things aren't quite going right.


ADVANCED: Deleting the record triggers deleting the calendar event!!!
If you'd like to have deleting the record you've been using be the trigger for also deleting the calendar event instead of some other method that preserves the record, then read on.

Make sure to create a deletion event, as I don't believe a condition on a notification can capture this.

Business Rule
Add this line to your business rule, or modify your current one for deleting.

if (current.operation() == 'delete') {
  gs.eventQueue("your deleted event name", null, Parm1: who this is sent to, Parm2: current.sys_id);
}

 

Notification

Check off "Event parm 1 contains recipient"

Template
BEGIN:VCALENDAR
PRODID:-//Service-now.com//Outlook 11.0 MIMEDIR//EN
VERSION:2.0
METHOD:CANCEL
BEGIN:VEVENT
STATUS:CANCELLED
ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=FALSE:MAILTO: ${to}
DTSTART:${dtstart}
DTEND:${dtend}
UID:${event.parm2}
DTSTAMP:${dtstamp}
DESCRIPTION:
END:VEVENT
END:VCALENDAR

 

 
Change the UID line to "UID:${event.parm2}". We need to do this because the notification won't be able to reference the record anymore as it's been deleted. This is how we provide the unique identifier so the invite going out can still match with the existing meeting invite that lives on a calendar.
If you added in your table name to the UID, the it'd be "UID:table_name${event.parm2}"

That should handle deleting calendar invites correctly. Please note that the attendee will have the old meeting disappear and it will show up as a 30 minute block in their calendar with a message along the lines of "This meeting has been deleted. Click to remove from calendar".
 

HTML in Meeting Invites from ServiceNow....Sort of

 

A big drawback of the iCalendar file type is that HTML is not supported in the description field when building up a new meeting. So how is it then that when making a normal meeting in Outlook/Gmail you can throw in some lovely HTML bits? The answer is another tag in the iCalendar type called "X-ALT-DESC". Before you get your hopes up though, this isn't very straightforward. X-ALT-DESC uses some XML schemas from schemas-microsoft-com to build up how the event looks. If you'd like to see what this looks like, I'd recommend making a meeting for yourself in your mail client, exporting it out, and taking a look at X-ALT-DESC. The <style> section contains all the good bits in it.

 

Something I have not tested, but might work best would be to get a calendar invite going out of ServiceNow into your own client, edit meeting in your client to pretty it up, then see if applying the X-ALT-DESC that appears after editing it into the iCalendar template in ServiceNow does the trick for keeping all of the styling in the future.

 

Troubleshooting
My calendar invite isn't sending.

Make sure that any conditions you set for the notification to send are being met, or that you can find the event in the event log if you are using events. It's generally easier to start with simple parameters and build them up from there than to start complex and work backwards.

I'm getting an email with an attachment and a message that says "This is not a valid .ics file".

Lots of places to check here. First is to make sure that the notification Type is a Meeting Invitation, that the Content type is Plain text only, and that you are using an Email Template to house the iCalendar code.
From there, check to make sure that your iCalendar code is placed in the Message Box or Message Text Box in the template, and not the Message HTML Box if you are using Eureka or higher versions of ServiceNow
Finally check to make sure that you have created and mapped your fields in the sys_impex_map table.

I get a meeting invite, but the start time is when the message was sent, and the end time is half an hour later.

Head on over to the sys_impex_map table and make sure that your entry their is titled icalendar.table_name. Again, if it is not in that format, it will not work correctly.
Also ensure that your dtstart and dtend fields in the sys_impex_map table are being mapped to date/time fields. Date fields will not work, nor will strings with dates and times in them.

 

Moving Forward
We're using a rather basic calendar invite here, but if you've sent out meeting invite in Outlook or any other mail client then you know there is the possibility for so much more. Reading through those websites for the iCalendar code will provide a lot of information. Another great trick is to create a meeting similar to one you'd want ServiceNow to send, saving it as an .ics file to your computer, then opening it in notepad++ or another editro to see what the code looks like for yourself.

I briefly mentioned that reoccurring events are incredibly hard to do earlier. They are not impossible, but a large quantity of new fields beyond the regular start and end dates are required. Things like defining time zones, day of the week codes, and several other items are required. They also need to be in a very peculiar format.

 


Taking calendar invite responses and updating a record in ServiceNow with it.

Author's Note (September 23rd, 2016): It is important to preface this section with a little note. I developed this solution while using Outlook 2016 and OWA. After moving to Office 365 however, the method described below doesn't function anymore, as the actual iCalendar code is attached to the inbound email instead of showing up in the body. As always, I strongly urge testing to see if this solution will work for you. If anyone has any suggestions on somehow including the iCalendar code in the body again (or getting ServiceNow to read the .ics attachment!), I'm all ears.
 
Update Feb 12th 2020: A few people have messaged me methods over time to read .ics files with ServiceNow, and I apologize since while I remember them doing it, I can't recall exactly who it was. For those needing to read an .ics file with ServiceNow, I recommend reading Ankur Bawiskar's response in this thread: https://community.servicenow.com/community?id=community_question&sys_id=da1f03e1dbdcdbc01dcaf3231f96...
 
As I never got to the bottom of the contents of a meeting invite coming into ServiceNow in either the sys_email body or an .ics file being Mail Server / Mail Client based, I'd recommend writing some inbound logic to account for either just to cover your bases.
 
If you have a need to know if an attendee or attendees responded to the invite, or if you'd like to know if they typed in any additional comments when they responded to the invite, then read on.

We will use an inbound email action to read the response, and then update some fields with the information that the inbound email action is able to glean.

Requirements
  • ORGANIZER:MAILTO in your iCalendar code is set to the email address for your instance
  • You have some knowledge as to how inbound email actions work and are able to script them
  • There is some place in the record that sends the calendar invite to insert the information we get back
NOTE: This was built on the assumption that the attendee is using Outlook (not O365). Other mail clients may return other information in the body of the email, so some trial and effort will be required to adjust your code to adapt for it.

 

The first thing to do is decide what kind of information are you interested in from the attendee's response, and where will it go. If you need to make new fields for this information then do so now, or you can always put this information in a journal field. Individual fields work well if there is only one attendee, whereas a journal field might work best if there are multiple attendees since it can capture who has responded and when over time.

Next is to head over to System Policy -> Email -> Inbound Actions and create a new Inbound Email Action

Once again, we will target the same table that we have kept on referencing over and over again, as it is the table that houses the record that initially triggered the calendar invite.
Type will be new, though if you want to capture if one of the attendees sent the invite to another person, I believe the type would then become a Forward.
The inbound email action has to do two things here:

  1. Figure out if an email coming into the system is a response to our calendar invite
  2. Break down the content of the email to just give us the useful bits
The first part can be a bit tricky, but I have a crafty solution.
Remember earlier in our iCalendar code how there is a line for the calendar invites UID, aka it's unique number? Normally you're fine with just putting ${sys_id}, but if we put the name of the table we're using before the sys_id so it looks like UID:your_table_name${sys_id}, this gives us an easy way to track down the emails we want.
From there, we can write a condition for the Inbound Email Action like looks something like - (email.body_text.indexOf('UID:table_name') > -1)
What this is telling the script to do is only process emails where it can see that UID:table_name piece in it.

 


Now to get the bits of the email we care about, since otherwise it will just spit back everything including the iCalendar code at us if we don't trim it down.

The best way to do this is by doing an indexOf for the UID:table_name. With that information we can do a slice and find the sys_id of the record we want to update. UID on its own might not be enough, in case someone typed a word with "uid" in it.
From there, run a GlideAggregate on the table we continuously use, and pull it up.
Meeting responses will appear in the subject line, so a simple IF statement with an indexOf for Accepted, Tentative, or Declined will find that information out for you.
Getting any additional notes that were typed in requires a bit more slicing. Do an indexOf "BEGIN:VCALENDAR", and this will return where the iCalendar code begins. We want the information before that, so doing a slice between 0 and where BEGIN:VCALENDAR   is will get us that information.
From there, write a little javascript to handle capturing the information you care about, then updating it to your record with a .update();

Example
var sbj = email.subject;       //email subject
var body = email.body_text;       //email body
var sysbody = body.indexOf('UID:table_name');
var sysid = body.slice(sysbody +12, sysbody + 44);       //get the custom identifier of the outlook event
//gs.log(sysid + 'sys id of table_name record');
 

//See if the sys_id from the subject line returns any records
var ga = new GlideAggregate('table_name');
ga.addAggregate('COUNT');
ga.addQuery('sys_id',sysid);ga.query();
var answer = 0;
if (ga.next()) {
  answer = gr.getAggregate('COUNT');
  //If there are no records, create a log
  if (answer == 0) {
    gs.log("No meeting response " + sbj);
    //Record has been found. Update the invite response fields
  } else {
    var gr = new GlideRecord('table_name');
    gr.addQuery('sys_id',sysid);
    gr.query();
    while (gr.next()){
      if (sbj.indexOf('Accepted') > -1){
        gr.u_invite_response = 3;
      } else if (sbj.indexOf('Tentative') > -1){
        gr.u_invite_response = 5;
      } else if (sbj.indexOf('Declined') > -1){
        gr.u_invite_response = 7;
      }
      var responsenotes = gr.u_invite_response_notes;
      var bslice = body.indexOf('BEGIN:VCALENDAR');
      if (bslice == -1) {
        gr.u_invite_response_notes = body + '\n\n' + responsenotes;
      } else if (bslice > 0) {
        var sbody = body.slice(0, bslice);
        gr.u_invite_response_notes = sbody + '\n\n' + responsenotes;
      }
      gr.update();
    }
  }
}

  


Troubleshooting

I don't see the response showing up in the email log for ServiceNow

Make sure that your instance's email address is set as the organizer in the iCalendar code. If you hardcoded this to your production instance, you will need to change it before you send a response to the calendar invite

I see the email in the log, but nothing is happening.

Check the email under System Mailboxes -> Inbound -> Received. You're able to watch and see as the Inbound Email Actions are taking any action on the received email or not. If there is a message that says "Skipping 'Your Inbound Email Action Name Here'", then that means the conditions are not lining up correctly.
If you can verify in the system log that the inbound email action is running, then that means something is wrong in the script. I recommend using gs.log to verify things like the sys_id of the record you want to update and make sure all 32 characters of it are there, if any IF statements you put is are running correctly, and that any fields you have set are named correctly. Also don't forget your .update() to update the record!

 


Hope this has been useful and informative. Good luck to everyone that wants to use this, and please feel free to add any suggestions or tricks you run across!

Feel free to comment, or find me over on the Community or LinkedIn if you have any further questions/suggestions/ideas. Thank you!
https://community.servicenow.com/people/bshelleyhttps://www.linkedin.com/in/bradfordshelley
Comments
Aman22
Mega Contributor

Has anyone implemented this for Team / Shared Calendar? The OOB implementation adds the invite to user calendar but our requirement is to add this to team calendars.

 

Thanks

Aman

pooja V1
Mega Guru

@Bradford Shelley 
Hello Shelley,

This blog really helped me creating a calendar invite. We have couple of new things needed to be add to invite. That is we need some message body with some styling added like background colors and images along with the meeting invite.

So, in the email template I added all the HTML and cycling code in 'Message HTML' and about calendar invite in 'Message Text'. In Notification I set the 'Type' is 'meeting invite' and 'content' is 'plain text only'.

After email is being trigged, it did not have the content from email template 'message html', only just meeting invite has been sent out.

Please suggest me a way I can complete this task by sending a meeting invite as well as the body styling and everything.

Thanks,

Pooja 

Pooja74
Giga Contributor

Hi @Bradford Shelley 

Thank you so much for article which helped me to create icalendar in better way .

Our client asking for response one when user accepts or decline it ,it should take some action but we are reviving mail in email logs but inbound action is not working properly kindly help below are the screenshots

Screenshot of icalendar codefind_real_file.png

Inbound action code

find_real_file.png

Michael Domke
Tera Guru

There is an issue with your code. In line 16, you're referencing "gr" to get the aggregate count when you should be referencing "ga". Change that and see if it helps.

Michael

Pooja74
Giga Contributor

Hi Mike,

Thank you for the response ,can you please help me for iCalendar code i have used ${URI_REF} as Shelly mentioned it wont give beautiful link is there any way we can fix this as it is looking odd link in the mail body.

thanks in advance!

pooja

alekhya11
Tera Expert

HI 
What have you done to solve this issue 

alekhya11
Tera Expert

HI Pooja, 
how did you solve this issue of adding Body to the meeting invite , please advise

Disha17
Kilo Explorer

Hello,

 

Did you manage to solve this issue?

Stanimir2
Giga Contributor

Hello, 

I've been trying to make an invite that has
to: one user
optional: list of users

but without success so far.

My email vcalendar template look like this:

BEGIN:VCALENDAR
PRODID:-//Service-now.com//Outlook 11.0 MIMEDIR//EN
VERSION:2.0
METHOD:REQUEST
BEGIN:VEVENT
ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:${to}
ORGANIZER:MAILTO:${from}
DTSTART:${dtstart}
DTEND:${dtend}
LOCATION:${location}
TRANSP:OPAQUE
SEQUENCE:${sys_mod_count}
UID:${sys_id}
DTSTAMP:${dtstamp}
DESCRIPTION:${description}
SUMMARY:${u_scheduled_summary}
PRIORITY:3
X-MICROSOFT-CDO-IMPORTANCE:${priority}
STATUS:CONFIRMED
CLASS:PUBLIC
X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 3.2//E
 N""><HTML><BODY> some hardcoded HTML template</BODY></HTML>
BEGIN:VALARM
TRIGGER:-PT60M
DESCRIPTION:Meeting reminder
ACTION:DISPLAY
END:VALARM
END:VEVENT
END:VCALENDAR

 

I am intercepting the vcalendar notification with a BR on sys_email table - before - Insert, that is adding the emails to the 'copied' field of the email.

Unfortunately, the list of users are not in the meeting invite - it is send only to the person that is passed to the notification as parm1

Ben Dye
Tera Contributor

Hello, I need to make it so when a CHG is requested, a calendar invite is sent out (pre-approval) at the time of creation, and then that invite gets updated when the CHG is approved and the time is established to do the CHG, which updates the Outlook calendar date and time automatically  upon approval. I've been looking for a solution to this and will continue to do so, but it's been long enough that I thought I'd throw the question up here and see if anyone has thoughts.

Edit - I see people don't respond to this very quickly, so just in case I may make a thread on this.

Tapish Sharma1
Kilo Sage

Hi,

Thanks for the article.... I am getting the script as it is in the email body and not a meeting invite ...what can be wrong here ?

Community Alums
Not applicable

@Bradford Shelle Thank you for this wonderful information.

Could you please inform me/suggest to me "how we can add recipients in CC for this kind of calendar invite notification?"

Thanks in advance.

 

Regards,

Ganesh

 

alexpullos
ServiceNow Employee
ServiceNow Employee

Hi @Bradford Shelle,

 

Thank you for this article! I have used your information to successfully send out a calendar invite with all of the information that I want it to contain.

 

The trouble that I'm having is that the invitation isn't editable once it arrives on my calendar. Should it be?

 

The invites are going out to a shared calendar that I own. Once the invite reaches my calendar, I'm not able to update it with a new date and time or modify the body of the message with new information. I'm also unable to delete the invite from the Outlook calendar app instance and must log into the Office 365 website. While I'm on the website, I can delete the event I'm still unable to modify the contents of the invite.

 

Is this something I should be able to do?

 

I've included my template for reference.

 

Thanks so much!

 

Alex

 

BEGIN:VCALENDAR
PRODID:-//Service-now.com//Outlook 11.0 MIMEDIR//EN
VERSION:2.0
METHOD:REQUEST
BEGIN:VEVENT
ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:${to}
ORGANIZER;CN="${u_producer}":MAILTO:Producer's email: ${u_producer_email}

[NOTE: I am the producer]
LOCATION:${u_recording_locaton}
RRULE:FREQ=DAILY;COUNT=0
DTSTART:${dtstart}
DTEND:${dtend}
UID:${sys_id}
DTSTAMP:${dtstamp}
DESCRIPTION:${description}
SUMMARY:${summary}
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-SNSYSID:${sys_id}
BEGIN:VALARM
TRIGGER:-PT15M
ACTION:DISPLAY
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR

pk16514
Tera Contributor

When I am sending invites, The organizer calender on outlook bydefault should be getting blocked but it's not happening although the attendees calender is getting blocked when they accept it. How to fix it?

 

payloadGen: function(momObj) {
        var startDate = this._formatDate(momObj.meeting_start_time);
        var endDate = this._formatDate(momObj.meeting_end_time);
        var payload = "";

        payload += "BEGIN:VCALENDAR\r\n";
        payload += "VERSION:2.0\r\n";
        payload += "PRODID:-//Service-now.com//Outlook 11.0 MIMEDIR//EN\r\n";
        payload += "METHOD:REQUEST\r\n";
        payload += "BEGIN:VEVENT\r\n";

        var momAttendees = new GlideRecord("x_4dai_minutes_attendees");
		momAttendees.addQuery("mom_number", momObj.sys_id);
		momAttendees.addQuery("attendees", "!=", momObj.organizer);
        momAttendees.query();
        while (momAttendees.next()) {
            // Add attendee user's email to mailto key in payload
            payload += "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:" + momAttendees.email + "\r\n";
        }

        payload += "ORGANIZER:" + momObj.organizer.email + "\r\n";
        payload += "DTSTART:" + startDate + "\r\n"; // Meeting start date
        payload += "DTEND:" + endDate + "\r\n"; // Meeting end date
        payload += "LOCATION:" + momObj.url + "\r\n"; // Meeting URL
        payload += "UID:" + momObj.getValue("sys_id") + "\r\n"; // sys_id of the minutes of meeting record 
        payload += "DTSTAMP:" + this._formatDate(new GlideDateTime().getValue()) + "\r\n";
        payload += "DESCRIPTION:" + "\r\n"; // Populate Conference details
        payload += "X-ALT-DESC;FMTTYPE=text/html:" + momObj.url + "\r\n";
        payload += "X-ALT-DESC;FMTTYPE=text/html:" + momObj.conference_details + "\r\n";
        payload += "SUMMARY:" + momObj.title + "\r\n"; // Populate title
        payload += "DESCRIPTION:Reminder\r\nEND:VALARM\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
        payload += "END:VEVENT\n";
        payload += "END:VCALENDAR\n";

        // Attach calendar invite to 'Minutes of meeting' record
        var addAttach = new GlideSysAttachment();
        addAttach.write(momObj, "Meeting_Invite[" + momObj.meeting_start_time + "].ics", 'text/calendar', payload);
    },
DeepiP
Tera Contributor

I want to add unsubscribe link on the calendar invite. I have added ${notif_unsub} in the body notification but in outlook calendar invite it's coming in html form and not forming Unsubscribe link.

zynsn
Tera Expert

Thanks for writing this article, it has been helpful to use to send calendar invites.

 

I have a question regarding iCalendar invites with multiple recipients. Since each attendee must be listed on a new line for the invite to be sent to all recipients, I'm facing an issue when raising the calendar invite through an event that includes my list of recipients in parm1 which is collected from a list collector. There doesn't appear to be a way to include all attendees from parm1 directly into the invite. As a workaround, I am using a before Insert business rule that runs on the sys_email table to edit the body of of the calendar invite before it's sent out.

 

Is using such business rule the only method to send a meeting invite to multiple recipients triggered by an event or is there a better approach?

Sathish Kumar S
Tera Expert

Hello @Bradford Shelle and all,

 

I have a requirement to amend the recipient for the OOTB Calendar invite on the change_request table where currently the invite is sent to the assigned_to field in the change_request. Now the business has asked to send the same calendar invite from change_request table to change_task assignment_group members. How to achieve this. Pls share some insights.

 

Regards,

Sathish

Rahulkalra
Tera Contributor

Hello Brad

 

I am facing one issue in this invite which was already implemented . Whenever user rejects the invite in Outlook it is creating Incident in ServiceNow which client don’t want . How to reboot this? Do you have any idea why it is creating incident in Servicenow?

 

regards

rahul

 

Rahulkalra
Tera Contributor

Hello @Bradford Shelle 

 

I am facing one issue in this invite which was already implemented . Whenever user rejects the invite in Outlook it is creating Incident in ServiceNow which client don’t want . How to reboot this? Do you have any idea why it is creating incident in Servicenow?

 

regards

rahul

 

Rahulkalra
Tera Contributor

Please help @Bradford Shelle  it’s urgent

Version history
Last update:
‎09-16-2016 05:19 AM
Updated by: