Creating a Public Calendar from Salesforce

Outcome

  • From two custom objects in Salesforce (one for the Calendar details and one for the Event details) create multiple custom calendars with events. The Calendars are served on their own page and have an ical Subscription button where people can subscribe to a feed of all the events on that calendar to show the events in their calendar.

  • All this information is to be shared publicly.

Tools used

  • AddEvent.com (excellent Calendar App)

  • Postman

  • Swagger

  • External Services

  • Custom Settings

  • Flow

AddEvent

Fabulous Features:

  • Custom Calendar Pages - on their own URL

  • Embeddable Calendar Pages - in your website

  • Good pricing

  • Absolutely fantastic support. I’ve aske the team and they have delivered so many features.

  • Custom Fields on the Calendar page and Event pages

Features I’m not using:

  • Custom event pages - as well as Custom Calendar Pages with just about any HTML mark up you can think of, you can do custom pages for each event.

  • Sharing the Event URLs - we will only share the Calendar URLs but you can just create individual events and share them if you want.

  • Requesting subscribers to submit details to subscribe to the calendar.

  • Event Locations or Organisers.

  • RSVPs for Events.

Steps

AddEvent

Set up AddEvent templates

  • Calendar Layout Template

  • Calendar Page Template

  • Colour Palette

Create and test your Calendar within the App

Grab your API Code from the Documentation https://www.addevent.com/documentation

Postman

Or any other API tool

  • Set up the POST to create a Calendar

  • Set up the POST to create a Calendar Event

  • Ensure you have ALL The fields you want for any type of Calendar or Event (eg I need some All Day Events, some Recurring Events, and

Hard code the values for now.

Create Calendar API Call

Test the API and ensure your Calendar looks the way you want it to.

Create Event API Call

Beware:

  • Make sure you have your BYDAY on your recurring to match the Start Date or you will get an incorrect result (the screen shot is incorrect)

  • Make sure your Event Timezone is the same as the Calendar Timezone

  • Make sure you have time between your start time and end time or the event won’t show

  • Make sure your end date is AFTER your start date or your event won’t show

  • The new line only works on the event page, not the event hover on the calendar

  • The chosen colour must be set in your colour palette first

Swagger

Now we are going to make the OpenAPI Spec to import into Salesforce to use in Flow

I use Swagger, you can build it yourself, or Mulesoft can do it too. There are probably other tools. Apparently Postman can do this too, but you know how you learn different tools for different things and just keep using them.

Generate the Swagger file from the Postman

  • Go to https://inspector.swagger.io/builder and Log in

  • Grab your full URL from the top of your Postman

  • Paste it in as a POST into Inspector

  • The Parameters will be shown

  • Change the name of the Calendar

  • Click Send

    • The Calendar will be created again

    • This means that Swagger Inspector now has the POST and the Response, we need both to create our OpenAPI spec

  • Click the item in the History

  • Click Create API Definition (ensure OAS 3.0 is selected)

 

  • Click Import OpenAPI

  • The API will be opened

Tidy Up

Now it’s time to tidy up the spec by removing hard coded values and replacing them with placeholders and adding good examples and descriptions

  • Use Placekitten for the example image

  • Eg the URL encoded string for the bannerimage custom data is

    %7B%22bannerimage%22%3A%22http%3A%2F%2Fplacekitten.com%2F200%2F300%22%7D

Export

Export the Spec as JSON Unresolved

My Calendar API is pasted here in full AddEventCreateCalendar and AddEventCreateEvent

External Services

Create Named Credential

Note this is the cheat way of doing External Services as the API itself is not authenticated. I have NEVER gotten External Services working with an authenticated Named Credential because I always give up because it seems to hard.

In this case all the information published on the calendars is public so I have no issues using an unauthenticated API.

External Services

  • Go to External Services

  • Click New External Service

  • Click From API Specification

  • Set up the External Service like this and PASTE in the full JSON that you downloaded

  • Cross your fingers (important!) and click Save & Next

  • Then follow the steps Next > Next

First Hurdle

Ah crapity crap, I’m two months or so ahead of myself. OpenAPI 3 is not supported until Spring '22 (February 22). I will leave these screen shots and rebuild my API as OpenAPI 2

Unfortunately the next screen shots will be for the OpenAPI 2 spec and it may be different when version 3 comes along.

At the end of this process you should have an ExternalService registered

NOTE:

Creating your own OpenAPI Spec to use in External Services means YOU are responsible for maintaining it if the API breaks (well they should use canonical versioning, but you never know), or if you need to make some business changes your end. It’s not ideal, but sometimes it is the best way. Just be aware of the trade-offs. Unfortunately, and especially because of no support for OpenAPI 3 yet, just plugging a fully qualified OpenAPI Spec’d endpoint into an External Service may not work (I’ve never gotten it to work). So hand crafting OpenAPI Specs is the only way.

Next do the same for your Create Event API Spec.

Salesforce Data Structure

This bit will be up to you, but this is what I’ve got

Parent Object

Field

Type

Maps to

Field

Type

Maps to

Calendar Name

Text

title

Calendar Description

Long Text

description

State

Picklist

 

Timezone

Formula
creates the Australia/Sydney from the state NSW etc

timezone

Calendar ID

Text

id (return)

Calendar Page URL

URL

link_long (return)

Calendar Unique Key

Text

uniquekey (return)

Calendar Edit URL

Formula (URL)
Adds /view onto the end of the Calendar Page URL

 

Calendar Colour

Formula
You might want to have a different colour depending on the type of the calendar. I will hard code this in the formula for now

calendar_color

Image URL

URL
I’m storing the images in Files and store the Public URL of the Image here

bannerimage in custom_data

Child Object

Representing each event in the Calendar

Field

Type

Maps to

Field

Type

Maps to

Calendar

Lookup

calendar_id

plus also get the timezone and potentially even color values from the parent object

Name

Event Name

title (or eventname - Internal Name) depending on how you want to do it

Recurrence

Picklist
Options for Weekly, Fortnightly, Monthly (I only have recurring events)

 

Event Description

Text

description

Event Start

Formula
(I can set the duration of each event to be 1 hr by default based on the date I enter)

end_date

Event End

Date / Time
(if you only ever have all day events this could be Date only)

start_date

All Day Event

Formula
based on if the Event End has a Time or some other business rule (I have a type of event that is all day and another type that is a particular time)

all_day_event

Recurring Rule

Formula
(or Flow to set the value. Depending on your events will depend on the complexity of this formula)

rrule

Optional fields for color, internalname

 

 

Custom Setting

Could be a CMDT but this is simple name value pairs and it’s much simpler to use Custom Settings in Flow so I’m going this way.

NOTE: as everything about this service is public I’m not particularly worried about the token so it’s find in a custom setting. DO NOT do this if you are doing something with more sensitive data.

Field

Type

Maps to

Field

Type

Maps to

Template Embed ID

Text

template_embed_id

Template ID

Text

template_id

Token

Text

token

Weekday Begin

Text

weekday_begin

Enter your data into your custom setting

Flow

Now this bit is important. We are going to create an Autolaunched Flow that all it does is takes in everything via parameters and returns data via parameters. NO DML, no links to anything else in this Flow!

The Custom Settings can be created as Formulas and get the data from the custom setting directly.

This is because if you EVER need to change the External Services Spec you can’t do it if it’s referenced in a Flow or any version of a Flow. So it’s easier to just delete the link to the Subflow, update the External Service and the Subflow and plug in the Subflow again.

  • I don’t need to set manual variables for the Output

  • Create an Assign Element to Assign the Output from the Create Calendar Action

  • To set the Variable for the output you need to traverse through the External Services model

    • I Output the Long URL as the CalendarURL, the UniqueKey and the CalendarID (I need the CalendarID to create the Event or edit the Calendar later).

    • For the event I don’t need to save anything but I will set up the Flow to Output the Event ID, Event URL and Unique Key just in case.

  • Remember to set your variables as Output Variables.

  • Save the Flow

  • Test your Subflow by running a Debug and passing values in

  • Wohooo!

Unfortunately my image didn’t work (customdata) I rebuilt it into a Text Template but it seems the new functionality on AddEvent doesn’t work again, so I’ve raised a support ticket. I will come back to that. (Apparently it was a glitch on their end).

Link it up to the Object

Now we are going to create another Flow (either Autolaunched or Screen Flow) to gather the data from the object to create the Calendar.

I won’t detail out this bit, it’s pretty specific to your org and where you are getting the fields from.

In my case I want each Calendar verified and checked before the Calendar and Events are being created. I only have two recurring events on each Calendar so in the one Screen Flow I will

  • Show the values that will be created in the Calendar based on my main Custom Object on a Flow Screen

  • Pass the details into the Create Calendar Subflow

  • Use the Outputs from the Create Calendar Subflow to update my main Custom Object

  • Use the ID from the Create Calendar Subflow to create the two events on the Calendar.

  • Show the link to the completed Calendar to the user for them to check.

The users will have the option to delete the calendar and start again if needed.

To create the Calendar then update the Parent Record, and then create the Calendar Events in the same Flow I had to put a Commit in after the initial update and before the External Services callout for the Calendar Event. This is the Commit Action that I used. (Or you could break it up into two Flows).

End Result

Unfortunately I can’t show you the final result as it’s in a client’s org but it is a really cool Flow that steps them through inputting custom things like the name of the Calendar and the name of the two Events, then creates the Calendar and the Two events, updates the Parent Record, then links that Parent record to a whole heap of other records to say “this is the correct Calendar for this record”. There will be 100 or so Calendars created in the first batch. Once they are all created we will send out comms to say “hey, here’s your new calendar for 2022 - subscribe here”, and they will get the link to their customised calendar.