- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 09-16-2016 05:19 AM
Update Feb 12, 2020: Official ServiceNow documentation for reference: https://docs.servicenow.com/bundle/newyork-servicenow-platform/page/administer/notification/referenc...
- 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*
- 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
- A little knowledge on how iCalendar works
- Creating notifications
- Creating email templates
- Creating business rules OPTIONAL
- Creating events OPTIONAL
- Basic Javascript
- How to Google
- 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
- Conditions that are built into a notification
- Event that triggers a notification, either through a business rule or workflow
- One event for new calendar invites
- One event for updating existing calendar invites
- One event for deleting existing calendar invites
if (current.operation() == 'insert') {
gs.eventQueue("change.inserted", current, gs.getUserID(), gs.getUserName());
}
- Select the table that we defined earlier and has our two date/time fields in it.
- 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.
- 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.
- 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
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.
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
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
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
TRIGGER:-PT15M - How soon before the meeting will the alarm pop up. In this example, it is for 15 minutes
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
if (current.operation() == 'delete') {
gs.eventQueue("your deleted event name", null, Parm1: who this is sent to, Parm2: current.sys_id);
}
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
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.
- 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
- Figure out if an email coming into the system is a response to our calendar invite
- Break down the content of the email to just give us the useful bits
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();
}
}
}
- 63,979 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi
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 code
Inbound action code
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
HI
What have you done to solve this issue
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
HI Pooja,
how did you solve this issue of adding Body to the meeting invite , please advise
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hello,
Did you manage to solve this issue?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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 ?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
@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
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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);
},
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Please help @Bradford Shelle it’s urgent
- « Previous
-
- 1
- 2
- Next »