Introducing Agical.io, the smarter ICS file generator | Community
Skip to main content
SanfordWhiteman
Level 10
August 3, 2016
Question

Introducing Agical.io, the smarter ICS file generator

  • August 3, 2016
  • 13 replies
  • 13354 views

If you've used Marketo's dynamic ICS files (the "Calendar File" token type) you're probably not completely happy with 'em.

About a year ago, I published a (free) microservice that fills in the biggest gaps. With a little more attention on it lately (read: 2 people cared!), I blogged about it.

Read more on TEKNKL :: Blog →

13 replies

August 3, 2016

Thanks sanford!

January 3, 2017

Hey Sanford,

I hope you're doing well. I'm trying to use the Agical.io ICS file generator you built and am running into an issue that I hope you can help me resolve. Thank you for creating this tool and offering it to the Marketo community.

I have two velocity scripting based tokens for the event start date and end date that are record specific and need to be in the URL for the ICS file. When I try to reference those tokens as values in a URL an extra space is added, causing the hyperlink to fail when clicked. By fail, I mean that the event start time and end time reders as a static value: 12/31/1969 4:00 PM. I believe this is due to the URL being rewritten by Marketo for tracking purposes. If you copy and paste the non-rewritten URL in a browser, the link works just fine.

Rewritten/tracked URL: em.sungevity.com/dc/s4ZLka5FfdFC9m1cmI_hrfzCmWMofwKTi4SUWBNAIw3LVZb3cBJV4iftjWnumggM45sqe1n3FwjsAI39bP3VjsLB2At9G…

Copied and pasted URL with populated custom tokens: http://ics.agical.io/?subject=Sungevity%20Home%20Visit&organizer=Sungevity&reminder=45&location=1205 Foster Ter&dtstart= 2017-01-04T23:00:00Z&dtend= 2017-01-04T20:00:00Z

See the spaces below. The issues looks specific to the token being included in a URL as the first two bullets are just non-linked token values. The rest are hyperlinks and are problematic. Please let me know if you have any ideas to resolve this issue. Thanks very much!

Daniel

SanfordWhiteman
Level 10
January 4, 2017

Are you positive there isn't whitespace being output from your script?  Remember, Velocity preserves whitespace like line breaks, because the output context may require it (think text part of an email as opposed to HTML part).

January 4, 2017

Thanks for your quick reply. That's great to know. I've removed all visible line breaks and spaces, but the link still populates with spaces. Do you have any other ideas for what could be causing the issue?

Here's script for the first token that's referenced as the dtstart parameter.

##Start of Script

## first want to grab the value of the home visit date time and convert it into format we want

## BASED ON SFDC CONFIG, ASSUMING THIS VALUE IS IN PST plus 2 hours

## used parseDate (string value, string format) within velocity

#set($dateObj = $convert.parseDate($Milestone1_Project__cList.get(0).Home_Visit_Date__c, 'yyyy-MM-dd HH:mm'))

## then we convert to a calendar object

#set($calendarObj = $convert.toCalendar($dateObj))

## comparing Time Zone on the Project and the to localize appointment time

#if ($Milestone1_Project__cList.get(0).Time_Zone__c == "EST" && $Milestone1_Project__cList.get(0).Home_Visit_Date__c.contains("12:00:00"))

## 10 represents 'hour' in calendar object?

## add 7 hours + 8 hours as it's translated into Greenwich in the final output.

$calendarObj.add(10,24)

#elseif ($Milestone1_Project__cList.get(0).Time_Zone__c == "CST" && $Milestone1_Project__cList.get(0).Home_Visit_Date__c.contains("12:00:00"))

$calendarObj.add(10,23)

#elseif ($Milestone1_Project__cList.get(0).Time_Zone__c == "MST" && $Milestone1_Project__cList.get(0).Home_Visit_Date__c.contains("12:00:00"))

$calendarObj.add(10,22)

#elseif ($Milestone1_Project__cList.get(0).Time_Zone__c == "PST" && $Milestone1_Project__cList.get(0).Home_Visit_Date__c.contains("12:00:00"))

$calendarObj.add(10,21)

## comparing Time Zone and value in Home Visit Date field to update all records that don't have an appointment at 12:00pm

#elseif ($Milestone1_Project__cList.get(0).Time_Zone__c == "EST" && !$Milestone1_Project__cList.get(0).Home_Visit_Date__c.contains("12:00:00"))

$calendarObj.add(10,12)

#elseif ($Milestone1_Project__cList.get(0).Time_Zone__c == "CST" && !$Milestone1_Project__cList.get(0).Home_Visit_Date__c.contains("12:00:00"))

$calendarObj.add(10,11)

#elseif ($Milestone1_Project__cList.get(0).Time_Zone__c == "MST" && !$Milestone1_Project__cList.get(0).Home_Visit_Date__c.contains("12:00:00"))

$calendarObj.add(10,10)

#elseif ($Milestone1_Project__cList.get(0).Time_Zone__c == "PST" && !$Milestone1_Project__cList.get(0).Home_Visit_Date__c.contains("12:00:00"))

$calendarObj.add(10,9)

#end

$date.format('yyyy-MM-dd',$calendarObj)T$date.format('HH:mm:ss',$calendarObj)Z

May 13, 2017

Great stuff, thanks Sanford. I think this is exactly what I am looking for.

Samantha_Cossum
Level 3
April 25, 2019

Hey Sanford,

I have a couple of questions that I couldn't fine addressed anywhere but if it is sorry for re-asking!

1. I'm having issues using the recur with Outlook. It works fine when I open the file into my iCal but when I open into Outlook it says all meetings occur in the past.

http://ics.agical.io/?subject=Submit+Your+Stats&organizer=Results+Creator+Bootcamp&reminder=0&location=simemembers.com&d…

2. Is there a way to set an end date for a recurring calendar? I tried setting the dtend but, at least in iCal, it just keeps going. The desire would be for the event to recur on the 1st every month and the final one to be on 02/01/2020. Here's what I tried:

http://ics.agical.io/?subject=Submit+Your+Stats&organizer=Results+Creator+Bootcamp&reminder=0&location=simemembers.com&d…

SanfordWhiteman
Level 10
April 25, 2019

Let's start with the first one.

The string "&replace00" looks pretty weird there. Are you sure you don't have a typo in the actual link sent to people (the sample URL you posted to the Nation is fine, but are you using {{lead.token}} or {{my.token}} in the email?). I'll do some more checking in Outlook if you tell me the exact version.

Samantha_Cossum
Level 3
April 25, 2019

No tokens just the straight link we are testing to use.

We're using outlook 2019 365 for Macs. Thanks for looking into this I really appreciate the help!

SanfordWhiteman
Level 10
May 30, 2019

You're embedding an unencoded URL in a URL, so you need to use the alternate query delimiter syntax (this isn't something specific to Agical, it's always the case).

Did you read the articles at https://blog.teknkl.com/tag/agical ?

Jyotsna_Gupta1
Level 2
May 30, 2019

Thanks for your quick reply.

In my case i am using 3 different URLs of ON24 in a description so {{member.webinar URL}} will not help. It is like a master calendar invite for the whole series (ON24 events are linked to subsequent programs). I am going to try this by encoding url as per your suggestion.

Could you please let me know the cause of endless occurrences of the event?

Thanks,

Jyotsna

SanfordWhiteman
Level 10
May 30, 2019

I'm not really talking about {{member.webinar URL}}. I'm talking about the general need to encode URLs-in-URLs, regardless of where they lead to.

I see spaces in your URLs, which indicates they haven't been run through an encoding step.

Could you please let me know the cause of endless occurrences of the event?

Fix the rest of the encoding up, then post a final rendered URL (with the tokens replaced by live data) as well as the template with the tokens shown.

Crystal_Pacheco
Level 3
July 24, 2019

I need to have line breaks in an event description for the calendar links in both outlook and google calendar. Looking to having my cake and eating it too. 

The event description is being used for both the google calendar link and the ics file link. \n works for Outlook but not for Google Calendar, <br> works for Google Calendar and not for Outlook. 

Linebreak codeWorks
<br>, %3Cbr%3EGoogleCal
\n, %0D%0A

ics

???

Both Google Cal and .ics


Is there one magical line break code thats compatible with both? Thanks for your time.

SanfordWhiteman
Level 10
July 24, 2019

Try it now with \n (real linebreak) in both places -- I changed GCal mode so it replaces \n with <br> automatically.

Crystal_Pacheco
Level 3
July 24, 2019

Thank you for your response, is the agical link still for : http://ics.agical.io/beta/alt_sep/  ? The gcal still printed \n

Crystal_Pacheco
Level 3
July 24, 2019

Thanks again, but you said you changed GCal mode so it replaces \n with <br> automatically. It didn't change automatically. If i use %0D%0A it line breaks for Gcal, but breaks the ics description after %0D%0A. \n works for ics but /n prints in gcal. There isn't a one code solution for line breaks in both formats yet?

SanfordWhiteman
Level 10
July 24, 2019

If i use %0D%0A it line breaks for Gcal, but breaks the ics description after %0D%0A.

That was what I meant by "automatically" because that's an standard encoded \n, which is transformed to <br> for Gcal now.

On the ICS side it seems like you want a the standard encoded \n to become a double-encoded \n, so that it ends up as a literal string "\n" (not LF, but literal backslash-n) in the ICS file. Let me look at that.

Crystal_Pacheco
Level 3
August 20, 2019

Hi there,

I would like to have a url in the calendar description. The problem is the URL has UTM codes in there using & , it works perfectly for ics file but not for gcal. Even with %26 or &amp; . It stops the description where the first & appears. I tried for both the beta/alt_sep version and the regular version of the agical link. 

 http://ics.agical.io/beta/alt_sep/?subject=This is a test: Again;description=Click here to attend: https://www.google.com/?utm_source=Overhere&utm_medium=testthis&utm_campaign=44444  You can test https://www.google.com/;dtstart=2019-09-05T15:00:00z;dtend=2019-09-05T16:00:00z;organizer=@this.com;location=Here;format=gcal;preencoded=true
 http://ics.agical.io/beta/alt_sep/?subject=This is a test: Again;description=Click%20here%20to%20attend%3A%20https%3A%2F%2Fwww.google.com%2F%2F15345%2F312187%3Futm_source=Overhere%26utm_medium=testthis%26utm_campaign=44444  You can test https%3A%2F%2Fwww.google.com;dtstart=2019-09-05T15:00:00z;dtend=2019-09-05T16:00:00z;organizer=@this.com;location=Here;format=gcal;preencoded=true

How do I make the & work here?

SanfordWhiteman
Level 10
August 22, 2019

You want

preencoded=false

because indeed you are not pre-URL-encoding the nested URL.

Please don't use /beta/, though, unless I've specifically mentioned that something is new/fixed in the Beta version only.

Crystal_Pacheco
Level 3
August 22, 2019

Excellent, thank you Sanford

Scott_Springer
Level 2
August 22, 2019

Hi Sanford, I've been testing your Agical.io service and it's very helpful to generate dynamic ICS files.

Could you tell me if there is a way to use the service without the "Z" GMT timezone hard coded in the ICS file. 

The reason is that we have date and time fields which are in coded in "local time" for a given client which already takes account Daylight Savings via the CRM. These fields work for text based appointment email reminders, but we would like to create an Add-To-Calendar function using local time.

Just for added context, we do have the DateTime ISO standard field, but its getting fed into Marketo via API which converts it to CST/CDT. To make this work for Australian time zones which also has Daylight Savings at a different time of year, I tried using the inbound/outbound time zone offset, and also tried manual offset, but i think there is no common reference point so that they adjust automatically all year round.

So far couldn't find a way to account for the two different daylight savings periods (Marketo USA + Australia), so I'm interested to know about the local time calendar option.

First time poster, I researched a lot on the topic, so hope this is right place. All other ideas welcome, we do a lot of appointment based communications, so I'll share our learnings as we go.

Scott_Springer
Level 2
August 23, 2019

So far, we have found a solution that will work following this method: https://nation.marketo.com/thread/47691-timezone-of-timestamps-on-custom-fields-of-opportunity-object-velocity.

Somehow, our "outTimeZone" from the proposed solution needed to be "Etc/UTC" rather than the Australia time zone, perhaps this is due to our source data having a built-in offset already.

  1. #set ($inTimeZone = $date.getTimeZone().getTimeZone('US/Central') )    
  2. #set ($outTimeZone = $date.getTimeZone().getTimeZone('Australia/Sydney') )    

If I've understood this right, the US/Central time zone will automatically update the required offset when Daylight Savings occurs. And we don't need to worry about the Australian time zones, since they are already captured in ISO DateTime format which should be relative to the Marketo time zone.

This Agical.co solution is critical to our post-appointment reminder system, many thanks to the creator and the forum shares.

SanfordWhiteman
Level 10
August 23, 2019

Yep, the key is to remember that the absence of an explicit timezone doesn't mean a timezone isn't silently used as part of the conversion to a date.

That's why you need to explicitly state the tz in both directions. Also, for future reference, make sure to read this: https://blog.teknkl.com/velocity-days-and-weeks/ 

Jyotsna_Gupta1
Level 2
December 13, 2019

Hi @Sanford Whiteman‌,

Pinging on agical again.

How can we set the recurrence to occur every fortnight? Or Can we set recurrence to occur after (n) days?

Thanks,

Jyotsna

SanfordWhiteman
Level 10
December 13, 2019

Fortnight, meaning every 2 weeks? Isn't that already an option

recur=daily&recurinterval=14‍